diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/Kconfig | 116 | ||||
| -rw-r--r-- | drivers/usb/core/Makefile | 5 | ||||
| -rw-r--r-- | drivers/usb/core/buffer.c | 33 | ||||
| -rw-r--r-- | drivers/usb/core/config.c | 138 | ||||
| -rw-r--r-- | drivers/usb/core/devices.c | 79 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 905 | ||||
| -rw-r--r-- | drivers/usb/core/driver.c | 787 | ||||
| -rw-r--r-- | drivers/usb/core/endpoint.c | 51 | ||||
| -rw-r--r-- | drivers/usb/core/file.c | 45 | ||||
| -rw-r--r-- | drivers/usb/core/generic.c | 12 | ||||
| -rw-r--r-- | drivers/usb/core/hcd-pci.c | 305 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 949 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 3552 | ||||
| -rw-r--r-- | drivers/usb/core/hub.h | 156 | ||||
| -rw-r--r-- | drivers/usb/core/inode.c | 776 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 264 | ||||
| -rw-r--r-- | drivers/usb/core/notify.c | 1 | ||||
| -rw-r--r-- | drivers/usb/core/port.c | 484 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 219 | ||||
| -rw-r--r-- | drivers/usb/core/sysfs.c | 576 | ||||
| -rw-r--r-- | drivers/usb/core/urb.c | 226 | ||||
| -rw-r--r-- | drivers/usb/core/usb-acpi.c | 228 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 139 | ||||
| -rw-r--r-- | drivers/usb/core/usb.h | 69 | 
24 files changed, 6768 insertions, 3347 deletions
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 9eed5b52d9d..1060657ca1b 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -1,18 +1,8 @@  #  # USB Core configuration  # -config USB_DEBUG -	bool "USB verbose debug messages" -	depends on USB -	help -	  Say Y here if you want the USB core & hub drivers to produce a bunch -	  of debug messages to the system log. Select this if you are having a -	  problem with USB support and want to see more of what is going on. -  config USB_ANNOUNCE_NEW_DEVICES  	bool "USB announce new devices" -	depends on USB -	default N  	help  	  Say Y here if you want the USB core to always announce the  	  idVendor, idProduct, Manufacturer, Product, and SerialNumber @@ -25,63 +15,24 @@ config USB_ANNOUNCE_NEW_DEVICES  	  log, or have any doubts about this, say N here.  comment "Miscellaneous USB options" -	depends on USB - -config USB_DEVICEFS -	bool "USB device filesystem (DEPRECATED)" -	depends on USB -	---help--- -	  If you say Y here (and to "/proc file system support" in the "File -	  systems" section, above), you will get a file /proc/bus/usb/devices -	  which lists the devices currently connected to your USB bus or -	  busses, and for every connected device a file named -	  "/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the -	  device number; the latter files can be used by user space programs -	  to talk directly to the device. These files are "virtual", meaning -	  they are generated on the fly and not stored on the hard drive. -	  You may need to mount the usbfs file system to see the files, use -	  mount -t usbfs none /proc/bus/usb - -	  For the format of the various /proc/bus/usb/ files, please read -	  <file:Documentation/usb/proc_usb_info.txt>. - -	  Modern Linux systems do not use this. - -	  Usbfs entries are files and not character devices; usbfs can't -	  handle Access Control Lists (ACL) which are the default way to -	  grant access to USB devices for untrusted users of a desktop -	  system. - -	  The usbfs functionality is replaced by real device-nodes managed by -	  udev.  These nodes lived in /dev/bus/usb and are used by libusb. - -config USB_DEVICE_CLASS -	bool "USB device class-devices (DEPRECATED)" -	depends on USB +config USB_DEFAULT_PERSIST +	bool "Enable USB persist by default"  	default y -	---help--- -	  Userspace access to USB devices is granted by device-nodes exported -	  directly from the usbdev in sysfs. Old versions of the driver -	  core and udev needed additional class devices to export device nodes. - -	  These additional devices are difficult to handle in userspace, if -	  information about USB interfaces must be available. One device -	  contains the device node, the other device contains the interface -	  data. Both devices are at the same level in sysfs (siblings) and one -	  can't access the other. The device node created directly by the -	  usb device is the parent device of the interface and therefore -	  easily accessible from the interface event. +	help +	  Say N here if you don't want USB power session persistence +	  enabled by default.  If you say N it will make suspended USB +	  devices that lose power get reenumerated as if they had been +	  unplugged, causing any mounted filesystems to be lost.  The +	  persist feature can still be enabled for individual devices +	  through the power/persist sysfs node. See +	  Documentation/usb/persist.txt for more info. -	  This option provides backward compatibility for libusb device -	  nodes (lsusb) when usbfs is not used, and the following udev rule -	  doesn't exist: -	    SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \ -	    NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" +	  If you have any questions about this, say Y here, only say N +	  if you know exactly what you are doing.  config USB_DYNAMIC_MINORS  	bool "Dynamic USB minor allocation" -	depends on USB  	help  	  If you say Y here, the USB subsystem will use dynamic minor  	  allocation for any device that uses the USB major number. @@ -90,34 +41,24 @@ config USB_DYNAMIC_MINORS  	  If you are unsure about this, say N here. -config USB_SUSPEND -	bool "USB runtime power management (autosuspend) and wakeup" -	depends on USB && PM_RUNTIME -	help -	  If you say Y here, you can use driver calls or the sysfs -	  "power/control" file to enable or disable autosuspend for -	  individual USB peripherals (see -	  Documentation/usb/power-management.txt for more details). - -	  Also, USB "remote wakeup" signaling is supported, whereby some -	  USB devices (like keyboards and network adapters) can wake up -	  their parent hub.  That wakeup cascades up the USB tree, and -	  could wake the system from states like suspend-to-RAM. - -	  If you are unsure about this, say N here. -  config USB_OTG -	bool -	depends on USB && EXPERIMENTAL -	depends on USB_SUSPEND +	bool "OTG support" +	depends on PM_RUNTIME  	default n +	help +	  The most notable feature of USB OTG is support for a +	  "Dual-Role" device, which can act as either a device +	  or a host. The initial role is decided by the type of +	  plug inserted and can be changed later when two dual +	  role devices talk to each other. +	  Select this only if your board has Mini-AB/Micro-AB +	  connector.  config USB_OTG_WHITELIST  	bool "Rely on OTG Targeted Peripherals List" -	depends on USB_OTG || EMBEDDED +	depends on USB_OTG || EXPERT  	default y if USB_OTG -	default n if EMBEDDED  	help  	  If you say Y here, the "otg_whitelist.h" file will be used as a  	  product whitelist, so USB peripherals not listed there will be @@ -133,10 +74,19 @@ config USB_OTG_WHITELIST  config USB_OTG_BLACKLIST_HUB  	bool "Disable external hubs" -	depends on USB_OTG || EMBEDDED +	depends on USB_OTG || EXPERT  	help  	  If you say Y here, then Linux will refuse to enumerate  	  external hubs.  OTG hosts are allowed to reduce hardware  	  and software costs by not supporting external hubs.  So  	  are "Embedded Hosts" that don't offer OTG support. +config USB_OTG_FSM +	tristate "USB 2.0 OTG FSM implementation" +	depends on USB +	select USB_OTG +	select USB_PHY +	help +	  Implements OTG Finite State Machine as specified in On-The-Go +	  and Embedded Host Supplement to the USB Revision 2.0 Specification. + diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 507a4e1b636..2f6f9322004 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -2,13 +2,12 @@  # Makefile for USB Core files and filesystem  # -ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG -  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o  usbcore-y += devio.o notify.o generic.o quirks.o devices.o +usbcore-y += port.o  usbcore-$(CONFIG_PCI)		+= hcd-pci.o -usbcore-$(CONFIG_USB_DEVICEFS)	+= inode.o +usbcore-$(CONFIG_ACPI)		+= usb-acpi.o  obj-$(CONFIG_USB)		+= usbcore.o diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 2c6965484fe..684ef70dc09 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -2,7 +2,7 @@   * DMA memory management for framework level HCD code (hc_driver)   *   * This implementation plugs in through generic "usb_bus" level methods, - * and should work with all USB controllers, regardles of bus type. + * and should work with all USB controllers, regardless of bus type.   */  #include <linux/module.h> @@ -10,7 +10,7 @@  #include <linux/slab.h>  #include <linux/device.h>  #include <linux/mm.h> -#include <asm/io.h> +#include <linux/io.h>  #include <linux/dma-mapping.h>  #include <linux/dmapool.h>  #include <linux/usb.h> @@ -22,7 +22,7 @@   */  /* FIXME tune these based on pool statistics ... */ -static const size_t	pool_max [HCD_BUFFER_POOLS] = { +static const size_t	pool_max[HCD_BUFFER_POOLS] = {  	/* platforms without dma-friendly caches might need to  	 * prevent cacheline sharing...  	 */ @@ -43,15 +43,16 @@ static const size_t	pool_max [HCD_BUFFER_POOLS] = {   *   * Call this as part of initializing a host controller that uses the dma   * memory allocators.  It initializes some pools of dma-coherent memory that - * will be shared by all drivers using that controller, or returns a negative - * errno value on error. + * will be shared by all drivers using that controller.   *   * Call hcd_buffer_destroy() to clean up after using those pools. + * + * Return: 0 if successful. A negative errno value otherwise.   */  int hcd_buffer_create(struct usb_hcd *hcd)  {  	char		name[16]; -	int 		i, size; +	int		i, size;  	if (!hcd->self.controller->dma_mask &&  	    !(hcd->driver->flags & HCD_LOCAL_MEM)) @@ -64,7 +65,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)  		snprintf(name, sizeof name, "buffer-%d", size);  		hcd->pool[i] = dma_pool_create(name, hcd->self.controller,  				size, size, 0); -		if (!hcd->pool [i]) { +		if (!hcd->pool[i]) {  			hcd_buffer_destroy(hcd);  			return -ENOMEM;  		} @@ -99,14 +100,14 @@ void hcd_buffer_destroy(struct usb_hcd *hcd)   */  void *hcd_buffer_alloc( -	struct usb_bus 	*bus, +	struct usb_bus		*bus,  	size_t			size,  	gfp_t			mem_flags,  	dma_addr_t		*dma  )  {  	struct usb_hcd		*hcd = bus_to_hcd(bus); -	int 			i; +	int			i;  	/* some USB hosts just use PIO */  	if (!bus->controller->dma_mask && @@ -116,21 +117,21 @@ void *hcd_buffer_alloc(  	}  	for (i = 0; i < HCD_BUFFER_POOLS; i++) { -		if (size <= pool_max [i]) -			return dma_pool_alloc(hcd->pool [i], mem_flags, dma); +		if (size <= pool_max[i]) +			return dma_pool_alloc(hcd->pool[i], mem_flags, dma);  	}  	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);  }  void hcd_buffer_free( -	struct usb_bus 	*bus, +	struct usb_bus		*bus,  	size_t			size, -	void 			*addr, +	void			*addr,  	dma_addr_t		dma  )  {  	struct usb_hcd		*hcd = bus_to_hcd(bus); -	int 			i; +	int			i;  	if (!addr)  		return; @@ -142,8 +143,8 @@ void hcd_buffer_free(  	}  	for (i = 0; i < HCD_BUFFER_POOLS; i++) { -		if (size <= pool_max [i]) { -			dma_pool_free(hcd->pool [i], addr, dma); +		if (size <= pool_max[i]) { +			dma_pool_free(hcd->pool[i], addr, dma);  			return;  		}  	} diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 83126b03e7c..1ab4df1de2d 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -3,7 +3,6 @@  #include <linux/usb/hcd.h>  #include <linux/usb/quirks.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/device.h>  #include <asm/byteorder.h> @@ -11,7 +10,6 @@  #define USB_MAXALTSETTING		128	/* Hard limit */ -#define USB_MAXENDPOINTS		30	/* Hard limit */  #define USB_MAXCONFIG			8	/* Arbitrary limit */ @@ -123,21 +121,22 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,  	}  	if (usb_endpoint_xfer_isoc(&ep->desc)) -		max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) * -			(desc->bmAttributes + 1); +		max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * +			usb_endpoint_maxp(&ep->desc);  	else if (usb_endpoint_xfer_int(&ep->desc)) -		max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); +		max_tx = usb_endpoint_maxp(&ep->desc) * +			(desc->bMaxBurst + 1);  	else  		max_tx = 999999; -	if (desc->wBytesPerInterval > max_tx) { +	if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) {  		dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in "  				"config %d interface %d altsetting %d ep %d: "  				"setting to %d\n",  				usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", -				desc->wBytesPerInterval, +				le16_to_cpu(desc->wBytesPerInterval),  				cfgno, inum, asnum, ep->desc.bEndpointAddress,  				max_tx); -		ep->ss_ep_comp.wBytesPerInterval = max_tx; +		ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);  	}  } @@ -240,7 +239,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,  		    cfgno, inum, asnum, d->bEndpointAddress);  		endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT;  		endpoint->desc.bInterval = 1; -		if (le16_to_cpu(endpoint->desc.wMaxPacketSize) > 8) +		if (usb_endpoint_maxp(&endpoint->desc) > 8)  			endpoint->desc.wMaxPacketSize = cpu_to_le16(8);  	} @@ -253,7 +252,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,  			&& usb_endpoint_xfer_bulk(d)) {  		unsigned maxp; -		maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff; +		maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff;  		if (maxp != 512)  			dev_warn(ddev, "config %d interface %d altsetting %d "  				"bulk endpoint 0x%X has invalid maxpacket %d\n", @@ -423,7 +422,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,  	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);  	if (config->desc.bDescriptorType != USB_DT_CONFIG || -	    config->desc.bLength < USB_DT_CONFIG_SIZE) { +	    config->desc.bLength < USB_DT_CONFIG_SIZE || +	    config->desc.bLength > size) {  		dev_err(ddev, "invalid descriptor for config index %d: "  		    "type = 0x%X, length = %d\n", cfgidx,  		    config->desc.bDescriptorType, config->desc.bLength); @@ -649,10 +649,6 @@ void usb_destroy_configuration(struct usb_device *dev)   *   * hub-only!! ... and only in reset path, or usb_new_device()   * (used by real hubs and virtual root hubs) - * - * NOTE: if this is a WUSB device and is not authorized, we skip the - *       whole thing. A non-authorized USB device has no - *       configurations.   */  int usb_get_configuration(struct usb_device *dev)  { @@ -664,8 +660,6 @@ int usb_get_configuration(struct usb_device *dev)  	struct usb_config_descriptor *desc;  	cfgno = 0; -	if (dev->authorized == 0)	/* Not really an error */ -		goto out_not_authorized;  	result = -ENOMEM;  	if (ncfg > USB_MAXCONFIG) {  		dev_warn(ddev, "too many configurations: %d, " @@ -701,6 +695,8 @@ int usb_get_configuration(struct usb_device *dev)  		if (result < 0) {  			dev_err(ddev, "unable to read config index %d "  			    "descriptor/%s: %d\n", cfgno, "start", result); +			if (result != -EPIPE) +				goto err;  			dev_err(ddev, "chopping to %d config(s)\n", cfgno);  			dev->descriptor.bNumConfigurations = cfgno;  			break; @@ -720,6 +716,10 @@ int usb_get_configuration(struct usb_device *dev)  			result = -ENOMEM;  			goto err;  		} + +		if (dev->quirks & USB_QUIRK_DELAY_INIT) +			msleep(100); +  		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,  		    bigbuffer, length);  		if (result < 0) { @@ -747,10 +747,112 @@ int usb_get_configuration(struct usb_device *dev)  err:  	kfree(desc); -out_not_authorized:  	dev->descriptor.bNumConfigurations = cfgno;  err2:  	if (result == -ENOMEM)  		dev_err(ddev, "out of memory\n");  	return result;  } + +void usb_release_bos_descriptor(struct usb_device *dev) +{ +	if (dev->bos) { +		kfree(dev->bos->desc); +		kfree(dev->bos); +		dev->bos = NULL; +	} +} + +/* Get BOS descriptor set */ +int usb_get_bos_descriptor(struct usb_device *dev) +{ +	struct device *ddev = &dev->dev; +	struct usb_bos_descriptor *bos; +	struct usb_dev_cap_header *cap; +	unsigned char *buffer; +	int length, total_len, num, i; +	int ret; + +	bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL); +	if (!bos) +		return -ENOMEM; + +	/* Get BOS descriptor */ +	ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE); +	if (ret < USB_DT_BOS_SIZE) { +		dev_err(ddev, "unable to get BOS descriptor\n"); +		if (ret >= 0) +			ret = -ENOMSG; +		kfree(bos); +		return ret; +	} + +	length = bos->bLength; +	total_len = le16_to_cpu(bos->wTotalLength); +	num = bos->bNumDeviceCaps; +	kfree(bos); +	if (total_len < length) +		return -EINVAL; + +	dev->bos = kzalloc(sizeof(struct usb_host_bos), GFP_KERNEL); +	if (!dev->bos) +		return -ENOMEM; + +	/* Now let's get the whole BOS descriptor set */ +	buffer = kzalloc(total_len, GFP_KERNEL); +	if (!buffer) { +		ret = -ENOMEM; +		goto err; +	} +	dev->bos->desc = (struct usb_bos_descriptor *)buffer; + +	ret = usb_get_descriptor(dev, USB_DT_BOS, 0, buffer, total_len); +	if (ret < total_len) { +		dev_err(ddev, "unable to get BOS descriptor set\n"); +		if (ret >= 0) +			ret = -ENOMSG; +		goto err; +	} +	total_len -= length; + +	for (i = 0; i < num; i++) { +		buffer += length; +		cap = (struct usb_dev_cap_header *)buffer; +		length = cap->bLength; + +		if (total_len < length) +			break; +		total_len -= length; + +		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { +			dev_warn(ddev, "descriptor type invalid, skip\n"); +			continue; +		} + +		switch (cap->bDevCapabilityType) { +		case USB_CAP_TYPE_WIRELESS_USB: +			/* Wireless USB cap descriptor is handled by wusb */ +			break; +		case USB_CAP_TYPE_EXT: +			dev->bos->ext_cap = +				(struct usb_ext_cap_descriptor *)buffer; +			break; +		case USB_SS_CAP_TYPE: +			dev->bos->ss_cap = +				(struct usb_ss_cap_descriptor *)buffer; +			break; +		case CONTAINER_ID_TYPE: +			dev->bos->ss_id = +				(struct usb_ss_container_id_descriptor *)buffer; +			break; +		default: +			break; +		} +	} + +	return 0; + +err: +	usb_release_bos_descriptor(dev); +	return ret; +} diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ddb4dc98092..2a3bbdf7eb9 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -54,7 +54,6 @@  #include <linux/gfp.h>  #include <linux/poll.h>  #include <linux/usb.h> -#include <linux/smp_lock.h>  #include <linux/usbdevice_fs.h>  #include <linux/usb/hcd.h>  #include <linux/mutex.h> @@ -65,49 +64,49 @@  /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */  #define ALLOW_SERIAL_NUMBER -static const char *format_topo = +static const char format_topo[] =  /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */  "\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; -static const char *format_string_manufacturer = +static const char format_string_manufacturer[] =  /* S:  Manufacturer=xxxx */    "S:  Manufacturer=%.100s\n"; -static const char *format_string_product = +static const char format_string_product[] =  /* S:  Product=xxxx */    "S:  Product=%.100s\n";  #ifdef ALLOW_SERIAL_NUMBER -static const char *format_string_serialnumber = +static const char format_string_serialnumber[] =  /* S:  SerialNumber=xxxx */    "S:  SerialNumber=%.100s\n";  #endif -static const char *format_bandwidth = +static const char format_bandwidth[] =  /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */    "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; -static const char *format_device1 = +static const char format_device1[] =  /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */    "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; -static const char *format_device2 = +static const char format_device2[] =  /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */    "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; -static const char *format_config = +static const char format_config[] =  /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */    "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; -static const char *format_iad = +static const char format_iad[] =  /* A:  FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */    "A:  FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; -static const char *format_iface = +static const char format_iface[] =  /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/    "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; -static const char *format_endpt = +static const char format_endpt[] =  /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */    "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; @@ -191,7 +190,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	dir = usb_endpoint_dir_in(desc) ? 'I' : 'O';  	if (speed == USB_SPEED_HIGH) { -		switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) { +		switch (usb_endpoint_maxp(desc) & (0x03 << 11)) {  		case 1 << 11:  			bandwidth = 2; break;  		case 2 << 11: @@ -222,7 +221,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  		break;  	case USB_ENDPOINT_XFER_INT:  		type = "Int."; -		if (speed == USB_SPEED_HIGH) +		if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER)  			interval = 1 << (desc->bInterval - 1);  		else  			interval = desc->bInterval; @@ -230,7 +229,8 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	default:	/* "can't happen" */  		return start;  	} -	interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000; +	interval *= (speed == USB_SPEED_HIGH || +		     speed == USB_SPEED_SUPER) ? 125 : 1000;  	if (interval % 1000)  		unit = 'u';  	else { @@ -240,7 +240,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,  			 desc->bmAttributes, type, -			 (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * +			 (usb_endpoint_maxp(desc) & 0x07ff) *  			 bandwidth,  			 interval, unit);  	return start; @@ -316,17 +316,23 @@ static char *usb_dump_iad_descriptor(char *start, char *end,   */  static char *usb_dump_config_descriptor(char *start, char *end,  				const struct usb_config_descriptor *desc, -				int active) +				int active, int speed)  { +	int mul; +  	if (start > end)  		return start; +	if (speed == USB_SPEED_SUPER) +		mul = 8; +	else +		mul = 2;  	start += sprintf(start, format_config,  			 /* mark active/actual/current cfg. */  			 active ? '*' : ' ',  			 desc->bNumInterfaces,  			 desc->bConfigurationValue,  			 desc->bmAttributes, -			 desc->bMaxPower * 2); +			 desc->bMaxPower * mul);  	return start;  } @@ -342,7 +348,8 @@ static char *usb_dump_config(int speed, char *start, char *end,  	if (!config)  		/* getting these some in 2.3.7; none in 2.3.6 */  		return start + sprintf(start, "(null Cfg. desc.)\n"); -	start = usb_dump_config_descriptor(start, end, &config->desc, active); +	start = usb_dump_config_descriptor(start, end, &config->desc, active, +			speed);  	for (i = 0; i < USB_MAXIADS; i++) {  		if (config->intf_assoc[i] == NULL)  			break; @@ -496,6 +503,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	char *pages_start, *data_end, *speed;  	unsigned int length;  	ssize_t total_written = 0; +	struct usb_device *childdev = NULL;  	/* don't bother with anything else if we're not writing any data */  	if (*nbytes <= 0) @@ -543,8 +551,9 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	if (level == 0) {  		int	max; -		/* high speed reserves 80%, full/low reserves 90% */ -		if (usbdev->speed == USB_SPEED_HIGH) +		/* super/high speed reserves 80%, full/low reserves 90% */ +		if (usbdev->speed == USB_SPEED_HIGH || +		    usbdev->speed == USB_SPEED_SUPER)  			max = 800;  		else  			max = FRAME_TIME_MAX_USECS_ALLOC; @@ -588,19 +597,15 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	free_pages((unsigned long)pages_start, 1);  	/* Now look at all of this device's children. */ -	for (chix = 0; chix < usbdev->maxchild; chix++) { -		struct usb_device *childdev = usbdev->children[chix]; - -		if (childdev) { -			usb_lock_device(childdev); -			ret = usb_device_dump(buffer, nbytes, skip_bytes, -					      file_offset, childdev, bus, -					      level + 1, chix, ++cnt); -			usb_unlock_device(childdev); -			if (ret == -EFAULT) -				return total_written; -			total_written += ret; -		} +	usb_hub_for_each_child(usbdev, chix, childdev) { +		usb_lock_device(childdev); +		ret = usb_device_dump(buffer, nbytes, skip_bytes, +				      file_offset, childdev, bus, +				      level + 1, chix - 1, ++cnt); +		usb_unlock_device(childdev); +		if (ret == -EFAULT) +			return total_written; +		total_written += ret;  	}  	return total_written;  } @@ -623,7 +628,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,  	/* print devices for all busses */  	list_for_each_entry(bus, &usb_bus_list, bus_list) {  		/* recurse through all children of the root hub */ -		if (!bus->root_hub) +		if (!bus_to_hcd(bus)->rh_registered)  			continue;  		usb_lock_device(bus->root_hub);  		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, @@ -660,7 +665,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)  {  	loff_t ret; -	mutex_lock(&file->f_dentry->d_inode->i_mutex); +	mutex_lock(&file_inode(file)->i_mutex);  	switch (orig) {  	case 0: @@ -676,7 +681,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)  		ret = -EINVAL;  	} -	mutex_unlock(&file->f_dentry->d_inode->i_mutex); +	mutex_unlock(&file_inode(file)->i_mutex);  	return ret;  } diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 045bb4b823e..257876ea03a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -37,29 +37,32 @@  #include <linux/fs.h>  #include <linux/mm.h>  #include <linux/slab.h> -#include <linux/smp_lock.h>  #include <linux/signal.h>  #include <linux/poll.h>  #include <linux/module.h> +#include <linux/string.h>  #include <linux/usb.h>  #include <linux/usbdevice_fs.h>  #include <linux/usb/hcd.h>	/* for usbcore internals */  #include <linux/cdev.h>  #include <linux/notifier.h>  #include <linux/security.h> -#include <asm/uaccess.h> +#include <linux/user_namespace.h> +#include <linux/scatterlist.h> +#include <linux/uaccess.h>  #include <asm/byteorder.h>  #include <linux/moduleparam.h>  #include "usb.h"  #define USB_MAXBUS			64 -#define USB_DEVICE_MAX			USB_MAXBUS * 128 +#define USB_DEVICE_MAX			(USB_MAXBUS * 128) +#define USB_SG_SIZE			16384 /* split-size for large txs */  /* Mutual exclusion for removal, open, and release */  DEFINE_MUTEX(usbfs_mutex); -struct dev_state { +struct usb_dev_state {  	struct list_head list;      /* state list */  	struct usb_device *dev;  	struct file *file; @@ -69,7 +72,7 @@ struct dev_state {  	wait_queue_head_t wait;     /* wake up if a request completed */  	unsigned int discsignr;  	struct pid *disc_pid; -	uid_t disc_uid, disc_euid; +	const struct cred *cred;  	void __user *disccontext;  	unsigned long ifclaimed;  	u32 secid; @@ -78,21 +81,22 @@ struct dev_state {  struct async {  	struct list_head asynclist; -	struct dev_state *ps; +	struct usb_dev_state *ps;  	struct pid *pid; -	uid_t uid, euid; +	const struct cred *cred;  	unsigned int signr;  	unsigned int ifnum;  	void __user *userbuffer;  	void __user *userurb;  	struct urb *urb; +	unsigned int mem_usage;  	int status;  	u32 secid;  	u8 bulk_addr;  	u8 bulk_status;  }; -static int usbfs_snoop; +static bool usbfs_snoop;  module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); @@ -108,10 +112,46 @@ enum snoop_when {  #define USB_DEVICE_DEV		MKDEV(USB_DEVICE_MAJOR, 0) -#define	MAX_USBFS_BUFFER_SIZE	16384 +/* Limit on the total amount of memory we can allocate for transfers */ +static unsigned usbfs_memory_mb = 16; +module_param(usbfs_memory_mb, uint, 0644); +MODULE_PARM_DESC(usbfs_memory_mb, +		"maximum MB allowed for usbfs buffers (0 = no limit)"); +/* Hard limit, necessary to avoid arithmetic overflow */ +#define USBFS_XFER_MAX		(UINT_MAX / 2 - 1000000) -static int connected(struct dev_state *ps) +static atomic_t usbfs_memory_usage;	/* Total memory currently allocated */ + +/* Check whether it's okay to allocate more memory for a transfer */ +static int usbfs_increase_memory_usage(unsigned amount) +{ +	unsigned lim; + +	/* +	 * Convert usbfs_memory_mb to bytes, avoiding overflows. +	 * 0 means use the hard limit (effectively unlimited). +	 */ +	lim = ACCESS_ONCE(usbfs_memory_mb); +	if (lim == 0 || lim > (USBFS_XFER_MAX >> 20)) +		lim = USBFS_XFER_MAX; +	else +		lim <<= 20; + +	atomic_add(amount, &usbfs_memory_usage); +	if (atomic_read(&usbfs_memory_usage) <= lim) +		return 0; +	atomic_sub(amount, &usbfs_memory_usage); +	return -ENOMEM; +} + +/* Memory for a transfer is being deallocated */ +static void usbfs_decrease_memory_usage(unsigned amount) +{ +	atomic_sub(amount, &usbfs_memory_usage); +} + +static int connected(struct usb_dev_state *ps)  {  	return (!list_empty(&ps->list) &&  			ps->dev->state != USB_STATE_NOTATTACHED); @@ -121,7 +161,7 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)  {  	loff_t ret; -	mutex_lock(&file->f_dentry->d_inode->i_mutex); +	mutex_lock(&file_inode(file)->i_mutex);  	switch (orig) {  	case 0: @@ -137,14 +177,14 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)  		ret = -EINVAL;  	} -	mutex_unlock(&file->f_dentry->d_inode->i_mutex); +	mutex_unlock(&file_inode(file)->i_mutex);  	return ret;  }  static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes,  			   loff_t *ppos)  { -	struct dev_state *ps = file->private_data; +	struct usb_dev_state *ps = file->private_data;  	struct usb_device *dev = ps->dev;  	ssize_t ret = 0;  	unsigned len; @@ -248,16 +288,26 @@ static struct async *alloc_async(unsigned int numisoframes)  static void free_async(struct async *as)  { +	int i; +  	put_pid(as->pid); +	if (as->cred) +		put_cred(as->cred); +	for (i = 0; i < as->urb->num_sgs; i++) { +		if (sg_page(&as->urb->sg[i])) +			kfree(sg_virt(&as->urb->sg[i])); +	} +	kfree(as->urb->sg);  	kfree(as->urb->transfer_buffer);  	kfree(as->urb->setup_packet);  	usb_free_urb(as->urb); +	usbfs_decrease_memory_usage(as->mem_usage);  	kfree(as);  }  static void async_newpending(struct async *as)  { -	struct dev_state *ps = as->ps; +	struct usb_dev_state *ps = as->ps;  	unsigned long flags;  	spin_lock_irqsave(&ps->lock, flags); @@ -267,7 +317,7 @@ static void async_newpending(struct async *as)  static void async_removepending(struct async *as)  { -	struct dev_state *ps = as->ps; +	struct usb_dev_state *ps = as->ps;  	unsigned long flags;  	spin_lock_irqsave(&ps->lock, flags); @@ -275,7 +325,7 @@ static void async_removepending(struct async *as)  	spin_unlock_irqrestore(&ps->lock, flags);  } -static struct async *async_getcompleted(struct dev_state *ps) +static struct async *async_getcompleted(struct usb_dev_state *ps)  {  	unsigned long flags;  	struct async *as = NULL; @@ -290,20 +340,17 @@ static struct async *async_getcompleted(struct dev_state *ps)  	return as;  } -static struct async *async_getpending(struct dev_state *ps, +static struct async *async_getpending(struct usb_dev_state *ps,  					     void __user *userurb)  { -	unsigned long flags;  	struct async *as; -	spin_lock_irqsave(&ps->lock, flags);  	list_for_each_entry(as, &ps->async_pending, asynclist)  		if (as->userurb == userurb) {  			list_del_init(&as->asynclist); -			spin_unlock_irqrestore(&ps->lock, flags);  			return as;  		} -	spin_unlock_irqrestore(&ps->lock, flags); +  	return NULL;  } @@ -351,13 +398,61 @@ static void snoop_urb(struct usb_device *udev,  	}  } +static void snoop_urb_data(struct urb *urb, unsigned len) +{ +	int i, size; + +	if (!usbfs_snoop) +		return; + +	if (urb->num_sgs == 0) { +		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, +			urb->transfer_buffer, len, 1); +		return; +	} + +	for (i = 0; i < urb->num_sgs && len; i++) { +		size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len; +		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, +			sg_virt(&urb->sg[i]), size, 1); +		len -= size; +	} +} + +static int copy_urb_data_to_user(u8 __user *userbuffer, struct urb *urb) +{ +	unsigned i, len, size; + +	if (urb->number_of_packets > 0)		/* Isochronous */ +		len = urb->transfer_buffer_length; +	else					/* Non-Isoc */ +		len = urb->actual_length; + +	if (urb->num_sgs == 0) { +		if (copy_to_user(userbuffer, urb->transfer_buffer, len)) +			return -EFAULT; +		return 0; +	} + +	for (i = 0; i < urb->num_sgs && len; i++) { +		size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len; +		if (copy_to_user(userbuffer, sg_virt(&urb->sg[i]), size)) +			return -EFAULT; +		userbuffer += size; +		len -= size; +	} + +	return 0; +} +  #define AS_CONTINUATION	1  #define AS_UNLINK	2 -static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr) +static void cancel_bulk_urbs(struct usb_dev_state *ps, unsigned bulk_addr)  __releases(ps->lock)  __acquires(ps->lock)  { +	struct urb *urb;  	struct async *as;  	/* Mark all the pending URBs that match bulk_addr, up to but not @@ -380,8 +475,11 @@ __acquires(ps->lock)  	list_for_each_entry(as, &ps->async_pending, asynclist) {  		if (as->bulk_status == AS_UNLINK) {  			as->bulk_status = 0;		/* Only once */ +			urb = as->urb; +			usb_get_urb(urb);  			spin_unlock(&ps->lock);		/* Allow completions */ -			usb_unlink_urb(as->urb); +			usb_unlink_urb(urb); +			usb_put_urb(urb);  			spin_lock(&ps->lock);  			goto rescan;  		} @@ -391,12 +489,11 @@ __acquires(ps->lock)  static void async_completed(struct urb *urb)  {  	struct async *as = urb->context; -	struct dev_state *ps = as->ps; +	struct usb_dev_state *ps = as->ps;  	struct siginfo sinfo;  	struct pid *pid = NULL; -	uid_t uid = 0; -	uid_t euid = 0;  	u32 secid = 0; +	const struct cred *cred = NULL;  	int signr;  	spin_lock(&ps->lock); @@ -408,30 +505,33 @@ static void async_completed(struct urb *urb)  		sinfo.si_errno = as->status;  		sinfo.si_code = SI_ASYNCIO;  		sinfo.si_addr = as->userurb; -		pid = as->pid; -		uid = as->uid; -		euid = as->euid; +		pid = get_pid(as->pid); +		cred = get_cred(as->cred);  		secid = as->secid;  	}  	snoop(&urb->dev->dev, "urb complete\n");  	snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, -			as->status, COMPLETE, -			((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_OUT) ? -				NULL : urb->transfer_buffer, urb->actual_length); +			as->status, COMPLETE, NULL, 0); +	if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN) +		snoop_urb_data(urb, urb->actual_length); +  	if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&  			as->status != -ENOENT)  		cancel_bulk_urbs(ps, as->bulk_addr);  	spin_unlock(&ps->lock); -	if (signr) -		kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, -				      euid, secid); +	if (signr) { +		kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred, secid); +		put_pid(pid); +		put_cred(cred); +	}  	wake_up(&ps->wait);  } -static void destroy_async(struct dev_state *ps, struct list_head *list) +static void destroy_async(struct usb_dev_state *ps, struct list_head *list)  { +	struct urb *urb;  	struct async *as;  	unsigned long flags; @@ -439,16 +539,19 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)  	while (!list_empty(list)) {  		as = list_entry(list->next, struct async, asynclist);  		list_del_init(&as->asynclist); +		urb = as->urb; +		usb_get_urb(urb);  		/* drop the spinlock so the completion handler can run */  		spin_unlock_irqrestore(&ps->lock, flags); -		usb_kill_urb(as->urb); +		usb_kill_urb(urb); +		usb_put_urb(urb);  		spin_lock_irqsave(&ps->lock, flags);  	}  	spin_unlock_irqrestore(&ps->lock, flags);  } -static void destroy_async_on_interface(struct dev_state *ps, +static void destroy_async_on_interface(struct usb_dev_state *ps,  				       unsigned int ifnum)  {  	struct list_head *p, *q, hitlist; @@ -463,7 +566,7 @@ static void destroy_async_on_interface(struct dev_state *ps,  	destroy_async(ps, &hitlist);  } -static void destroy_all_async(struct dev_state *ps) +static void destroy_all_async(struct usb_dev_state *ps)  {  	destroy_async(ps, &ps->async_pending);  } @@ -482,7 +585,7 @@ static int driver_probe(struct usb_interface *intf,  static void driver_disconnect(struct usb_interface *intf)  { -	struct dev_state *ps = usb_get_intfdata(intf); +	struct usb_dev_state *ps = usb_get_intfdata(intf);  	unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber;  	if (!ps) @@ -525,7 +628,7 @@ struct usb_driver usbfs_driver = {  	.resume =	driver_resume,  }; -static int claimintf(struct dev_state *ps, unsigned int ifnum) +static int claimintf(struct usb_dev_state *ps, unsigned int ifnum)  {  	struct usb_device *dev = ps->dev;  	struct usb_interface *intf; @@ -547,7 +650,7 @@ static int claimintf(struct dev_state *ps, unsigned int ifnum)  	return err;  } -static int releaseintf(struct dev_state *ps, unsigned int ifnum) +static int releaseintf(struct usb_dev_state *ps, unsigned int ifnum)  {  	struct usb_device *dev;  	struct usb_interface *intf; @@ -567,7 +670,7 @@ static int releaseintf(struct dev_state *ps, unsigned int ifnum)  	return err;  } -static int checkintf(struct dev_state *ps, unsigned int ifnum) +static int checkintf(struct usb_dev_state *ps, unsigned int ifnum)  {  	if (ps->dev->state != USB_STATE_CONFIGURED)  		return -EHOSTUNREACH; @@ -607,10 +710,11 @@ static int findintfep(struct usb_device *dev, unsigned int ep)  	return -ENOENT;  } -static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, -			   unsigned int index) +static int check_ctrlrecip(struct usb_dev_state *ps, unsigned int requesttype, +			   unsigned int request, unsigned int index)  {  	int ret = 0; +	struct usb_host_interface *alt_setting;  	if (ps->dev->state != USB_STATE_UNAUTHENTICATED  	 && ps->dev->state != USB_STATE_ADDRESS @@ -619,10 +723,41 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,  	if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))  		return 0; +	/* +	 * check for the special corner case 'get_device_id' in the printer +	 * class specification, which we always want to allow as it is used +	 * to query things like ink level, etc. +	 */ +	if (requesttype == 0xa1 && request == 0) { +		alt_setting = usb_find_alt_setting(ps->dev->actconfig, +						   index >> 8, index & 0xff); +		if (alt_setting +		 && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER) +			return 0; +	} +  	index &= 0xff;  	switch (requesttype & USB_RECIP_MASK) {  	case USB_RECIP_ENDPOINT: +		if ((index & ~USB_DIR_IN) == 0) +			return 0;  		ret = findintfep(ps->dev, index); +		if (ret < 0) { +			/* +			 * Some not fully compliant Win apps seem to get +			 * index wrong and have the endpoint number here +			 * rather than the endpoint address (with the +			 * correct direction). Win does let this through, +			 * so we'll not reject it here but leave it to +			 * the device to not break KVM. But we warn. +			 */ +			ret = findintfep(ps->dev, index ^ 0x80); +			if (ret >= 0) +				dev_info(&ps->dev->dev, +					"%s: process %i (%s) requesting ep %02x but needs %02x\n", +					__func__, task_pid_nr(current), +					current->comm, index, index ^ 0x80); +		}  		if (ret >= 0)  			ret = checkintf(ps, ret);  		break; @@ -634,6 +769,88 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,  	return ret;  } +static struct usb_host_endpoint *ep_to_host_endpoint(struct usb_device *dev, +						     unsigned char ep) +{ +	if (ep & USB_ENDPOINT_DIR_MASK) +		return dev->ep_in[ep & USB_ENDPOINT_NUMBER_MASK]; +	else +		return dev->ep_out[ep & USB_ENDPOINT_NUMBER_MASK]; +} + +static int parse_usbdevfs_streams(struct usb_dev_state *ps, +				  struct usbdevfs_streams __user *streams, +				  unsigned int *num_streams_ret, +				  unsigned int *num_eps_ret, +				  struct usb_host_endpoint ***eps_ret, +				  struct usb_interface **intf_ret) +{ +	unsigned int i, num_streams, num_eps; +	struct usb_host_endpoint **eps; +	struct usb_interface *intf = NULL; +	unsigned char ep; +	int ifnum, ret; + +	if (get_user(num_streams, &streams->num_streams) || +	    get_user(num_eps, &streams->num_eps)) +		return -EFAULT; + +	if (num_eps < 1 || num_eps > USB_MAXENDPOINTS) +		return -EINVAL; + +	/* The XHCI controller allows max 2 ^ 16 streams */ +	if (num_streams_ret && (num_streams < 2 || num_streams > 65536)) +		return -EINVAL; + +	eps = kmalloc(num_eps * sizeof(*eps), GFP_KERNEL); +	if (!eps) +		return -ENOMEM; + +	for (i = 0; i < num_eps; i++) { +		if (get_user(ep, &streams->eps[i])) { +			ret = -EFAULT; +			goto error; +		} +		eps[i] = ep_to_host_endpoint(ps->dev, ep); +		if (!eps[i]) { +			ret = -EINVAL; +			goto error; +		} + +		/* usb_alloc/free_streams operate on an usb_interface */ +		ifnum = findintfep(ps->dev, ep); +		if (ifnum < 0) { +			ret = ifnum; +			goto error; +		} + +		if (i == 0) { +			ret = checkintf(ps, ifnum); +			if (ret < 0) +				goto error; +			intf = usb_ifnum_to_if(ps->dev, ifnum); +		} else { +			/* Verify all eps belong to the same interface */ +			if (ifnum != intf->altsetting->desc.bInterfaceNumber) { +				ret = -EINVAL; +				goto error; +			} +		} +	} + +	if (num_streams_ret) +		*num_streams_ret = num_streams; +	*num_eps_ret = num_eps; +	*eps_ret = eps; +	*intf_ret = intf; + +	return 0; + +error: +	kfree(eps); +	return ret; +} +  static int match_devt(struct device *dev, void *data)  {  	return dev->devt == (dev_t) (unsigned long) data; @@ -656,12 +873,11 @@ static struct usb_device *usbdev_lookup_by_devt(dev_t devt)  static int usbdev_open(struct inode *inode, struct file *file)  {  	struct usb_device *dev = NULL; -	struct dev_state *ps; -	const struct cred *cred = current_cred(); +	struct usb_dev_state *ps;  	int ret;  	ret = -ENOMEM; -	ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); +	ps = kmalloc(sizeof(struct usb_dev_state), GFP_KERNEL);  	if (!ps)  		goto out_free_ps; @@ -674,17 +890,6 @@ static int usbdev_open(struct inode *inode, struct file *file)  	if (imajor(inode) == USB_DEVICE_MAJOR)  		dev = usbdev_lookup_by_devt(inode->i_rdev); -#ifdef CONFIG_USB_DEVICEFS -	/* procfs file */ -	if (!dev) { -		dev = inode->i_private; -		if (dev && dev->usbfs_dentry && -					dev->usbfs_dentry->d_inode == inode) -			usb_get_dev(dev); -		else -			dev = NULL; -	} -#endif  	mutex_unlock(&usbfs_mutex);  	if (!dev) @@ -707,8 +912,7 @@ static int usbdev_open(struct inode *inode, struct file *file)  	init_waitqueue_head(&ps->wait);  	ps->discsignr = 0;  	ps->disc_pid = get_pid(task_pid(current)); -	ps->disc_uid = cred->uid; -	ps->disc_euid = cred->euid; +	ps->cred = get_current_cred();  	ps->disccontext = NULL;  	ps->ifclaimed = 0;  	security_task_getsecid(current, &ps->secid); @@ -730,7 +934,7 @@ static int usbdev_open(struct inode *inode, struct file *file)  static int usbdev_release(struct inode *inode, struct file *file)  { -	struct dev_state *ps = file->private_data; +	struct usb_dev_state *ps = file->private_data;  	struct usb_device *dev = ps->dev;  	unsigned int ifnum;  	struct async *as; @@ -750,6 +954,7 @@ static int usbdev_release(struct inode *inode, struct file *file)  	usb_unlock_device(dev);  	usb_put_dev(dev);  	put_pid(ps->disc_pid); +	put_cred(ps->cred);  	as = async_getcompleted(ps);  	while (as) { @@ -760,7 +965,7 @@ static int usbdev_release(struct inode *inode, struct file *file)  	return 0;  } -static int proc_control(struct dev_state *ps, void __user *arg) +static int proc_control(struct usb_dev_state *ps, void __user *arg)  {  	struct usb_device *dev = ps->dev;  	struct usbdevfs_ctrltransfer ctrl; @@ -771,28 +976,33 @@ static int proc_control(struct dev_state *ps, void __user *arg)  	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))  		return -EFAULT; -	ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); +	ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest, +			      ctrl.wIndex);  	if (ret)  		return ret;  	wLength = ctrl.wLength;		/* To suppress 64k PAGE_SIZE warning */  	if (wLength > PAGE_SIZE)  		return -EINVAL; +	ret = usbfs_increase_memory_usage(PAGE_SIZE + sizeof(struct urb) + +			sizeof(struct usb_ctrlrequest)); +	if (ret) +		return ret;  	tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); -	if (!tbuf) -		return -ENOMEM; +	if (!tbuf) { +		ret = -ENOMEM; +		goto done; +	}  	tmo = ctrl.timeout;  	snoop(&dev->dev, "control urb: bRequestType=%02x "  		"bRequest=%02x wValue=%04x "  		"wIndex=%04x wLength=%04x\n", -		ctrl.bRequestType, ctrl.bRequest, -		__le16_to_cpup(&ctrl.wValue), -		__le16_to_cpup(&ctrl.wIndex), -		__le16_to_cpup(&ctrl.wLength)); +		ctrl.bRequestType, ctrl.bRequest, ctrl.wValue, +		ctrl.wIndex, ctrl.wLength);  	if (ctrl.bRequestType & 0x80) {  		if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,  					       ctrl.wLength)) { -			free_page((unsigned long)tbuf); -			return -EINVAL; +			ret = -EINVAL; +			goto done;  		}  		pipe = usb_rcvctrlpipe(dev, 0);  		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0); @@ -803,18 +1013,18 @@ static int proc_control(struct dev_state *ps, void __user *arg)  				    tbuf, ctrl.wLength, tmo);  		usb_lock_device(dev);  		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, -			tbuf, i); +			  tbuf, max(i, 0));  		if ((i > 0) && ctrl.wLength) {  			if (copy_to_user(ctrl.data, tbuf, i)) { -				free_page((unsigned long)tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  	} else {  		if (ctrl.wLength) {  			if (copy_from_user(tbuf, ctrl.data, ctrl.wLength)) { -				free_page((unsigned long)tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  		pipe = usb_sndctrlpipe(dev, 0); @@ -828,17 +1038,21 @@ static int proc_control(struct dev_state *ps, void __user *arg)  		usb_lock_device(dev);  		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0);  	} -	free_page((unsigned long)tbuf);  	if (i < 0 && i != -EPIPE) {  		dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "  			   "failed cmd %s rqt %u rq %u len %u ret %d\n",  			   current->comm, ctrl.bRequestType, ctrl.bRequest,  			   ctrl.wLength, i);  	} -	return i; +	ret = i; + done: +	free_page((unsigned long) tbuf); +	usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) + +			sizeof(struct usb_ctrlrequest)); +	return ret;  } -static int proc_bulk(struct dev_state *ps, void __user *arg) +static int proc_bulk(struct usb_dev_state *ps, void __user *arg)  {  	struct usb_device *dev = ps->dev;  	struct usbdevfs_bulktransfer bulk; @@ -862,15 +1076,20 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  	if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))  		return -EINVAL;  	len1 = bulk.len; -	if (len1 > MAX_USBFS_BUFFER_SIZE) +	if (len1 >= USBFS_XFER_MAX)  		return -EINVAL; -	if (!(tbuf = kmalloc(len1, GFP_KERNEL))) -		return -ENOMEM; +	ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); +	if (ret) +		return ret; +	if (!(tbuf = kmalloc(len1, GFP_KERNEL))) { +		ret = -ENOMEM; +		goto done; +	}  	tmo = bulk.timeout;  	if (bulk.ep & 0x80) {  		if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) { -			kfree(tbuf); -			return -EINVAL; +			ret = -EINVAL; +			goto done;  		}  		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); @@ -881,15 +1100,15 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  		if (!i && len2) {  			if (copy_to_user(bulk.data, tbuf, len2)) { -				kfree(tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  	} else {  		if (len1) {  			if (copy_from_user(tbuf, bulk.data, len1)) { -				kfree(tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); @@ -899,13 +1118,28 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  		usb_lock_device(dev);  		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0);  	} +	ret = (i < 0 ? i : len2); + done:  	kfree(tbuf); -	if (i < 0) -		return i; -	return len2; +	usbfs_decrease_memory_usage(len1 + sizeof(struct urb)); +	return ret; +} + +static void check_reset_of_active_ep(struct usb_device *udev, +		unsigned int epnum, char *ioctl_name) +{ +	struct usb_host_endpoint **eps; +	struct usb_host_endpoint *ep; + +	eps = (epnum & USB_DIR_IN) ? udev->ep_in : udev->ep_out; +	ep = eps[epnum & 0x0f]; +	if (ep && !list_empty(&ep->urb_list)) +		dev_warn(&udev->dev, "Process %d (%s) called USBDEVFS_%s for active endpoint 0x%02x\n", +				task_pid_nr(current), current->comm, +				ioctl_name, epnum);  } -static int proc_resetep(struct dev_state *ps, void __user *arg) +static int proc_resetep(struct usb_dev_state *ps, void __user *arg)  {  	unsigned int ep;  	int ret; @@ -918,11 +1152,12 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)  	ret = checkintf(ps, ret);  	if (ret)  		return ret; +	check_reset_of_active_ep(ps->dev, ep, "RESETEP");  	usb_reset_endpoint(ps->dev, ep);  	return 0;  } -static int proc_clearhalt(struct dev_state *ps, void __user *arg) +static int proc_clearhalt(struct usb_dev_state *ps, void __user *arg)  {  	unsigned int ep;  	int pipe; @@ -936,6 +1171,7 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg)  	ret = checkintf(ps, ret);  	if (ret)  		return ret; +	check_reset_of_active_ep(ps->dev, ep, "CLEAR_HALT");  	if (ep & USB_DIR_IN)  		pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f);  	else @@ -944,7 +1180,7 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg)  	return usb_clear_halt(ps->dev, pipe);  } -static int proc_getdriver(struct dev_state *ps, void __user *arg) +static int proc_getdriver(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_getdriver gd;  	struct usb_interface *intf; @@ -956,14 +1192,14 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)  	if (!intf || !intf->dev.driver)  		ret = -ENODATA;  	else { -		strncpy(gd.driver, intf->dev.driver->name, +		strlcpy(gd.driver, intf->dev.driver->name,  				sizeof(gd.driver));  		ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0);  	}  	return ret;  } -static int proc_connectinfo(struct dev_state *ps, void __user *arg) +static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_connectinfo ci = {  		.devnum = ps->dev->devnum, @@ -975,12 +1211,12 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)  	return 0;  } -static int proc_resetdevice(struct dev_state *ps) +static int proc_resetdevice(struct usb_dev_state *ps)  {  	return usb_reset_device(ps->dev);  } -static int proc_setintf(struct dev_state *ps, void __user *arg) +static int proc_setintf(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_setinterface setintf;  	int ret; @@ -989,11 +1225,14 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)  		return -EFAULT;  	if ((ret = checkintf(ps, setintf.interface)))  		return ret; + +	destroy_async_on_interface(ps, setintf.interface); +  	return usb_set_interface(ps->dev, setintf.interface,  			setintf.altsetting);  } -static int proc_setconfig(struct dev_state *ps, void __user *arg) +static int proc_setconfig(struct usb_dev_state *ps, void __user *arg)  {  	int u;  	int status = 0; @@ -1041,18 +1280,19 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg)  	return status;  } -static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, +static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb,  			struct usbdevfs_iso_packet_desc __user *iso_frame_desc,  			void __user *arg)  {  	struct usbdevfs_iso_packet_desc *isopkt = NULL;  	struct usb_host_endpoint *ep; -	struct async *as; +	struct async *as = NULL;  	struct usb_ctrlrequest *dr = NULL; -	const struct cred *cred = current_cred();  	unsigned int u, totlen, isofrmlen; -	int ret, ifnum = -1; -	int is_in; +	int i, ret, is_in, num_sgs = 0, ifnum = -1; +	int number_of_packets = 0; +	unsigned int stream_id = 0; +	void *buf;  	if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |  				USBDEVFS_URB_SHORT_NOT_OK | @@ -1072,42 +1312,34 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		if (ret)  			return ret;  	} -	if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { -		is_in = 1; -		ep = ps->dev->ep_in[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; -	} else { -		is_in = 0; -		ep = ps->dev->ep_out[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; -	} +	ep = ep_to_host_endpoint(ps->dev, uurb->endpoint);  	if (!ep)  		return -ENOENT; +	is_in = (uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0; + +	u = 0;  	switch(uurb->type) {  	case USBDEVFS_URB_TYPE_CONTROL:  		if (!usb_endpoint_xfer_control(&ep->desc))  			return -EINVAL; -		/* min 8 byte setup packet, -		 * max 8 byte setup plus an arbitrary data stage */ -		if (uurb->buffer_length < 8 || -		    uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) +		/* min 8 byte setup packet */ +		if (uurb->buffer_length < 8)  			return -EINVAL;  		dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);  		if (!dr)  			return -ENOMEM;  		if (copy_from_user(dr, uurb->buffer, 8)) { -			kfree(dr); -			return -EFAULT; +			ret = -EFAULT; +			goto error;  		}  		if (uurb->buffer_length < (le16_to_cpup(&dr->wLength) + 8)) { -			kfree(dr); -			return -EINVAL; +			ret = -EINVAL; +			goto error;  		} -		ret = check_ctrlrecip(ps, dr->bRequestType, +		ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest,  				      le16_to_cpup(&dr->wIndex)); -		if (ret) { -			kfree(dr); -			return ret; -		} -		uurb->number_of_packets = 0; +		if (ret) +			goto error;  		uurb->buffer_length = le16_to_cpup(&dr->wLength);  		uurb->buffer += 8;  		if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { @@ -1124,6 +1356,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			__le16_to_cpup(&dr->wValue),  			__le16_to_cpup(&dr->wIndex),  			__le16_to_cpup(&dr->wLength)); +		u = sizeof(struct usb_ctrlrequest);  		break;  	case USBDEVFS_URB_TYPE_BULK: @@ -1136,18 +1369,17 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			uurb->type = USBDEVFS_URB_TYPE_INTERRUPT;  			goto interrupt_urb;  		} -		uurb->number_of_packets = 0; -		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) -			return -EINVAL; +		num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); +		if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) +			num_sgs = 0; +		if (ep->streams) +			stream_id = uurb->stream_id;  		break;  	case USBDEVFS_URB_TYPE_INTERRUPT:  		if (!usb_endpoint_xfer_int(&ep->desc))  			return -EINVAL;   interrupt_urb: -		uurb->number_of_packets = 0; -		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) -			return -EINVAL;  		break;  	case USBDEVFS_URB_TYPE_ISO: @@ -1157,63 +1389,113 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			return -EINVAL;  		if (!usb_endpoint_xfer_isoc(&ep->desc))  			return -EINVAL; +		number_of_packets = uurb->number_of_packets;  		isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * -				   uurb->number_of_packets; +				   number_of_packets;  		if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))  			return -ENOMEM;  		if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { -			kfree(isopkt); -			return -EFAULT; +			ret = -EFAULT; +			goto error;  		} -		for (totlen = u = 0; u < uurb->number_of_packets; u++) { -			/* arbitrary limit, -			 * sufficient for USB 2.0 high-bandwidth iso */ -			if (isopkt[u].length > 8192) { -				kfree(isopkt); -				return -EINVAL; +		for (totlen = u = 0; u < number_of_packets; u++) { +			/* +			 * arbitrary limit need for USB 3.0 +			 * bMaxBurst (0~15 allowed, 1~16 packets) +			 * bmAttributes (bit 1:0, mult 0~2, 1~3 packets) +			 * sizemax: 1024 * 16 * 3 = 49152 +			 */ +			if (isopkt[u].length > 49152) { +				ret = -EINVAL; +				goto error;  			}  			totlen += isopkt[u].length;  		} -		/* 3072 * 64 microframes */ -		if (totlen > 196608) { -			kfree(isopkt); -			return -EINVAL; -		} +		u *= sizeof(struct usb_iso_packet_descriptor);  		uurb->buffer_length = totlen;  		break;  	default:  		return -EINVAL;  	} + +	if (uurb->buffer_length >= USBFS_XFER_MAX) { +		ret = -EINVAL; +		goto error; +	}  	if (uurb->buffer_length > 0 &&  			!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,  				uurb->buffer, uurb->buffer_length)) { -		kfree(isopkt); -		kfree(dr); -		return -EFAULT; +		ret = -EFAULT; +		goto error;  	} -	as = alloc_async(uurb->number_of_packets); +	as = alloc_async(number_of_packets);  	if (!as) { -		kfree(isopkt); -		kfree(dr); -		return -ENOMEM; +		ret = -ENOMEM; +		goto error;  	} -	if (uurb->buffer_length > 0) { + +	u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length + +	     num_sgs * sizeof(struct scatterlist); +	ret = usbfs_increase_memory_usage(u); +	if (ret) +		goto error; +	as->mem_usage = u; + +	if (num_sgs) { +		as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), +				      GFP_KERNEL); +		if (!as->urb->sg) { +			ret = -ENOMEM; +			goto error; +		} +		as->urb->num_sgs = num_sgs; +		sg_init_table(as->urb->sg, as->urb->num_sgs); + +		totlen = uurb->buffer_length; +		for (i = 0; i < as->urb->num_sgs; i++) { +			u = (totlen > USB_SG_SIZE) ? USB_SG_SIZE : totlen; +			buf = kmalloc(u, GFP_KERNEL); +			if (!buf) { +				ret = -ENOMEM; +				goto error; +			} +			sg_set_buf(&as->urb->sg[i], buf, u); + +			if (!is_in) { +				if (copy_from_user(buf, uurb->buffer, u)) { +					ret = -EFAULT; +					goto error; +				} +				uurb->buffer += u; +			} +			totlen -= u; +		} +	} else if (uurb->buffer_length > 0) {  		as->urb->transfer_buffer = kmalloc(uurb->buffer_length,  				GFP_KERNEL);  		if (!as->urb->transfer_buffer) { -			kfree(isopkt); -			kfree(dr); -			free_async(as); -			return -ENOMEM; +			ret = -ENOMEM; +			goto error;  		} -		/* Isochronous input data may end up being discontiguous -		 * if some of the packets are short.  Clear the buffer so -		 * that the gaps don't leak kernel data to userspace. -		 */ -		if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) + +		if (!is_in) { +			if (copy_from_user(as->urb->transfer_buffer, +					   uurb->buffer, +					   uurb->buffer_length)) { +				ret = -EFAULT; +				goto error; +			} +		} else if (uurb->type == USBDEVFS_URB_TYPE_ISO) { +			/* +			 * Isochronous input data may end up being +			 * discontiguous if some of the packets are short. +			 * Clear the buffer so that the gaps don't leak +			 * kernel data to userspace. +			 */  			memset(as->urb->transfer_buffer, 0,  					uurb->buffer_length); +		}  	}  	as->urb->dev = ps->dev;  	as->urb->pipe = (uurb->type << 30) | @@ -1239,8 +1521,10 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  	as->urb->transfer_buffer_length = uurb->buffer_length;  	as->urb->setup_packet = (unsigned char *)dr; +	dr = NULL;  	as->urb->start_frame = uurb->start_frame; -	as->urb->number_of_packets = uurb->number_of_packets; +	as->urb->number_of_packets = number_of_packets; +	as->urb->stream_id = stream_id;  	if (uurb->type == USBDEVFS_URB_TYPE_ISO ||  			ps->dev->speed == USB_SPEED_HIGH)  		as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); @@ -1248,12 +1532,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		as->urb->interval = ep->desc.bInterval;  	as->urb->context = as;  	as->urb->complete = async_completed; -	for (totlen = u = 0; u < uurb->number_of_packets; u++) { +	for (totlen = u = 0; u < number_of_packets; u++) {  		as->urb->iso_frame_desc[u].offset = totlen;  		as->urb->iso_frame_desc[u].length = isopkt[u].length;  		totlen += isopkt[u].length;  	}  	kfree(isopkt); +	isopkt = NULL;  	as->ps = ps;  	as->userurb = arg;  	if (is_in && uurb->buffer_length > 0) @@ -1263,20 +1548,14 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  	as->signr = uurb->signr;  	as->ifnum = ifnum;  	as->pid = get_pid(task_pid(current)); -	as->uid = cred->uid; -	as->euid = cred->euid; +	as->cred = get_current_cred();  	security_task_getsecid(current, &as->secid); -	if (!is_in && uurb->buffer_length > 0) { -		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, -				uurb->buffer_length)) { -			free_async(as); -			return -EFAULT; -		} -	}  	snoop_urb(ps->dev, as->userurb, as->urb->pipe,  			as->urb->transfer_buffer_length, 0, SUBMIT, -			is_in ? NULL : as->urb->transfer_buffer, -				uurb->buffer_length); +			NULL, 0); +	if (!is_in) +		snoop_urb_data(as->urb, as->urb->transfer_buffer_length); +  	async_newpending(as);  	if (usb_endpoint_xfer_bulk(&ep->desc)) { @@ -1316,13 +1595,19 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		snoop_urb(ps->dev, as->userurb, as->urb->pipe,  				0, ret, COMPLETE, NULL, 0);  		async_removepending(as); -		free_async(as); -		return ret; +		goto error;  	}  	return 0; + + error: +	kfree(isopkt); +	kfree(dr); +	if (as) +		free_async(as); +	return ret;  } -static int proc_submiturb(struct dev_state *ps, void __user *arg) +static int proc_submiturb(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_urb uurb; @@ -1334,14 +1619,26 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)  			arg);  } -static int proc_unlinkurb(struct dev_state *ps, void __user *arg) +static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg)  { +	struct urb *urb;  	struct async *as; +	unsigned long flags; +	spin_lock_irqsave(&ps->lock, flags);  	as = async_getpending(ps, arg); -	if (!as) +	if (!as) { +		spin_unlock_irqrestore(&ps->lock, flags);  		return -EINVAL; -	usb_kill_urb(as->urb); +	} + +	urb = as->urb; +	usb_get_urb(urb); +	spin_unlock_irqrestore(&ps->lock, flags); + +	usb_kill_urb(urb); +	usb_put_urb(urb); +  	return 0;  } @@ -1353,11 +1650,7 @@ static int processcompl(struct async *as, void __user * __user *arg)  	unsigned int i;  	if (as->userbuffer && urb->actual_length) { -		if (urb->number_of_packets > 0)		/* Isochronous */ -			i = urb->transfer_buffer_length; -		else					/* Non-Isoc */ -			i = urb->actual_length; -		if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) +		if (copy_urb_data_to_user(as->userbuffer, urb))  			goto err_out;  	}  	if (put_user(as->status, &userurb->status)) @@ -1386,7 +1679,7 @@ err_out:  	return -EFAULT;  } -static struct async *reap_as(struct dev_state *ps) +static struct async *reap_as(struct usb_dev_state *ps)  {  	DECLARE_WAITQUEUE(wait, current);  	struct async *as = NULL; @@ -1409,7 +1702,7 @@ static struct async *reap_as(struct dev_state *ps)  	return as;  } -static int proc_reapurb(struct dev_state *ps, void __user *arg) +static int proc_reapurb(struct usb_dev_state *ps, void __user *arg)  {  	struct async *as = reap_as(ps);  	if (as) { @@ -1422,7 +1715,7 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)  	return -EIO;  } -static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) +static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)  {  	int retval;  	struct async *as; @@ -1437,37 +1730,37 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)  }  #ifdef CONFIG_COMPAT -static int proc_control_compat(struct dev_state *ps, +static int proc_control_compat(struct usb_dev_state *ps,  				struct usbdevfs_ctrltransfer32 __user *p32)  { -        struct usbdevfs_ctrltransfer __user *p; -        __u32 udata; -        p = compat_alloc_user_space(sizeof(*p)); -        if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) || -            get_user(udata, &p32->data) || +	struct usbdevfs_ctrltransfer __user *p; +	__u32 udata; +	p = compat_alloc_user_space(sizeof(*p)); +	if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) || +	    get_user(udata, &p32->data) ||  	    put_user(compat_ptr(udata), &p->data))  		return -EFAULT; -        return proc_control(ps, p); +	return proc_control(ps, p);  } -static int proc_bulk_compat(struct dev_state *ps, +static int proc_bulk_compat(struct usb_dev_state *ps,  			struct usbdevfs_bulktransfer32 __user *p32)  { -        struct usbdevfs_bulktransfer __user *p; -        compat_uint_t n; -        compat_caddr_t addr; +	struct usbdevfs_bulktransfer __user *p; +	compat_uint_t n; +	compat_caddr_t addr; -        p = compat_alloc_user_space(sizeof(*p)); +	p = compat_alloc_user_space(sizeof(*p)); -        if (get_user(n, &p32->ep) || put_user(n, &p->ep) || -            get_user(n, &p32->len) || put_user(n, &p->len) || -            get_user(n, &p32->timeout) || put_user(n, &p->timeout) || -            get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data)) -                return -EFAULT; +	if (get_user(n, &p32->ep) || put_user(n, &p->ep) || +	    get_user(n, &p32->len) || put_user(n, &p->len) || +	    get_user(n, &p32->timeout) || put_user(n, &p->timeout) || +	    get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data)) +		return -EFAULT; -        return proc_bulk(ps, p); +	return proc_bulk(ps, p);  } -static int proc_disconnectsignal_compat(struct dev_state *ps, void __user *arg) +static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_disconnectsignal32 ds; @@ -1505,7 +1798,7 @@ static int get_urb32(struct usbdevfs_urb *kurb,  	return 0;  } -static int proc_submiturb_compat(struct dev_state *ps, void __user *arg) +static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_urb uurb; @@ -1524,10 +1817,10 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)  	void __user *addr = as->userurb;  	unsigned int i; -	if (as->userbuffer && urb->actual_length) -		if (copy_to_user(as->userbuffer, urb->transfer_buffer, -				 urb->actual_length)) +	if (as->userbuffer && urb->actual_length) { +		if (copy_urb_data_to_user(as->userbuffer, urb))  			return -EFAULT; +	}  	if (put_user(as->status, &userurb->status))  		return -EFAULT;  	if (put_user(urb->actual_length, &userurb->actual_length)) @@ -1551,7 +1844,7 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)  	return 0;  } -static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) +static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg)  {  	struct async *as = reap_as(ps);  	if (as) { @@ -1564,7 +1857,7 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)  	return -EIO;  } -static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) +static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *arg)  {  	int retval;  	struct async *as; @@ -1581,7 +1874,7 @@ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)  #endif -static int proc_disconnectsignal(struct dev_state *ps, void __user *arg) +static int proc_disconnectsignal(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_disconnectsignal ds; @@ -1592,7 +1885,7 @@ static int proc_disconnectsignal(struct dev_state *ps, void __user *arg)  	return 0;  } -static int proc_claiminterface(struct dev_state *ps, void __user *arg) +static int proc_claiminterface(struct usb_dev_state *ps, void __user *arg)  {  	unsigned int ifnum; @@ -1601,7 +1894,7 @@ static int proc_claiminterface(struct dev_state *ps, void __user *arg)  	return claimintf(ps, ifnum);  } -static int proc_releaseinterface(struct dev_state *ps, void __user *arg) +static int proc_releaseinterface(struct usb_dev_state *ps, void __user *arg)  {  	unsigned int ifnum;  	int ret; @@ -1614,7 +1907,7 @@ static int proc_releaseinterface(struct dev_state *ps, void __user *arg)  	return 0;  } -static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) +static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl)  {  	int			size;  	void			*buf = NULL; @@ -1624,7 +1917,8 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)  	/* alloc buffer */  	if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) { -		if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) +		buf = kmalloc(size, GFP_KERNEL); +		if (buf == NULL)  			return -ENOMEM;  		if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) {  			if (copy_from_user(buf, ctl->data, size)) { @@ -1689,7 +1983,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)  	return retval;  } -static int proc_ioctl_default(struct dev_state *ps, void __user *arg) +static int proc_ioctl_default(struct usb_dev_state *ps, void __user *arg)  {  	struct usbdevfs_ioctl	ctrl; @@ -1699,7 +1993,7 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg)  }  #ifdef CONFIG_COMPAT -static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) +static int proc_ioctl_compat(struct usb_dev_state *ps, compat_uptr_t arg)  {  	struct usbdevfs_ioctl32 __user *uioc;  	struct usbdevfs_ioctl ctrl; @@ -1717,7 +2011,7 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg)  }  #endif -static int proc_claim_port(struct dev_state *ps, void __user *arg) +static int proc_claim_port(struct usb_dev_state *ps, void __user *arg)  {  	unsigned portnum;  	int rc; @@ -1731,7 +2025,7 @@ static int proc_claim_port(struct dev_state *ps, void __user *arg)  	return rc;  } -static int proc_release_port(struct dev_state *ps, void __user *arg) +static int proc_release_port(struct usb_dev_state *ps, void __user *arg)  {  	unsigned portnum; @@ -1740,6 +2034,93 @@ static int proc_release_port(struct dev_state *ps, void __user *arg)  	return usb_hub_release_port(ps->dev, portnum, ps);  } +static int proc_get_capabilities(struct usb_dev_state *ps, void __user *arg) +{ +	__u32 caps; + +	caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; +	if (!ps->dev->bus->no_stop_on_short) +		caps |= USBDEVFS_CAP_BULK_CONTINUATION; +	if (ps->dev->bus->sg_tablesize) +		caps |= USBDEVFS_CAP_BULK_SCATTER_GATHER; + +	if (put_user(caps, (__u32 __user *)arg)) +		return -EFAULT; + +	return 0; +} + +static int proc_disconnect_claim(struct usb_dev_state *ps, void __user *arg) +{ +	struct usbdevfs_disconnect_claim dc; +	struct usb_interface *intf; + +	if (copy_from_user(&dc, arg, sizeof(dc))) +		return -EFAULT; + +	intf = usb_ifnum_to_if(ps->dev, dc.interface); +	if (!intf) +		return -EINVAL; + +	if (intf->dev.driver) { +		struct usb_driver *driver = to_usb_driver(intf->dev.driver); + +		if ((dc.flags & USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER) && +				strncmp(dc.driver, intf->dev.driver->name, +					sizeof(dc.driver)) != 0) +			return -EBUSY; + +		if ((dc.flags & USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER) && +				strncmp(dc.driver, intf->dev.driver->name, +					sizeof(dc.driver)) == 0) +			return -EBUSY; + +		dev_dbg(&intf->dev, "disconnect by usbfs\n"); +		usb_driver_release_interface(driver, intf); +	} + +	return claimintf(ps, dc.interface); +} + +static int proc_alloc_streams(struct usb_dev_state *ps, void __user *arg) +{ +	unsigned num_streams, num_eps; +	struct usb_host_endpoint **eps; +	struct usb_interface *intf; +	int r; + +	r = parse_usbdevfs_streams(ps, arg, &num_streams, &num_eps, +				   &eps, &intf); +	if (r) +		return r; + +	destroy_async_on_interface(ps, +				   intf->altsetting[0].desc.bInterfaceNumber); + +	r = usb_alloc_streams(intf, eps, num_eps, num_streams, GFP_KERNEL); +	kfree(eps); +	return r; +} + +static int proc_free_streams(struct usb_dev_state *ps, void __user *arg) +{ +	unsigned num_eps; +	struct usb_host_endpoint **eps; +	struct usb_interface *intf; +	int r; + +	r = parse_usbdevfs_streams(ps, arg, NULL, &num_eps, &eps, &intf); +	if (r) +		return r; + +	destroy_async_on_interface(ps, +				   intf->altsetting[0].desc.bInterfaceNumber); + +	r = usb_free_streams(intf, eps, num_eps, GFP_KERNEL); +	kfree(eps); +	return r; +} +  /*   * NOTE:  All requests here that have interface numbers as parameters   * are assuming that somehow the configuration has been prevented from @@ -1748,8 +2129,8 @@ static int proc_release_port(struct dev_state *ps, void __user *arg)  static long usbdev_do_ioctl(struct file *file, unsigned int cmd,  				void __user *p)  { -	struct dev_state *ps = file->private_data; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct usb_dev_state *ps = file->private_data; +	struct inode *inode = file_inode(file);  	struct usb_device *dev = ps->dev;  	int ret = -ENOTTY; @@ -1910,6 +2291,18 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,  		snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__);  		ret = proc_release_port(ps, p);  		break; +	case USBDEVFS_GET_CAPABILITIES: +		ret = proc_get_capabilities(ps, p); +		break; +	case USBDEVFS_DISCONNECT_CLAIM: +		ret = proc_disconnect_claim(ps, p); +		break; +	case USBDEVFS_ALLOC_STREAMS: +		ret = proc_alloc_streams(ps, p); +		break; +	case USBDEVFS_FREE_STREAMS: +		ret = proc_free_streams(ps, p); +		break;  	}  	usb_unlock_device(dev);  	if (ret >= 0) @@ -1943,7 +2336,7 @@ static long usbdev_compat_ioctl(struct file *file, unsigned int cmd,  static unsigned int usbdev_poll(struct file *file,  				struct poll_table_struct *wait)  { -	struct dev_state *ps = file->private_data; +	struct usb_dev_state *ps = file->private_data;  	unsigned int mask = 0;  	poll_wait(file, &ps->wait, wait); @@ -1969,11 +2362,11 @@ const struct file_operations usbdev_file_operations = {  static void usbdev_remove(struct usb_device *udev)  { -	struct dev_state *ps; +	struct usb_dev_state *ps;  	struct siginfo sinfo;  	while (!list_empty(&udev->filelist)) { -		ps = list_entry(udev->filelist.next, struct dev_state, list); +		ps = list_entry(udev->filelist.next, struct usb_dev_state, list);  		destroy_all_async(ps);  		wake_up_all(&ps->wait);  		list_del_init(&ps->list); @@ -1982,51 +2375,19 @@ static void usbdev_remove(struct usb_device *udev)  			sinfo.si_errno = EPIPE;  			sinfo.si_code = SI_ASYNCIO;  			sinfo.si_addr = ps->disccontext; -			kill_pid_info_as_uid(ps->discsignr, &sinfo, -					ps->disc_pid, ps->disc_uid, -					ps->disc_euid, ps->secid); +			kill_pid_info_as_cred(ps->discsignr, &sinfo, +					ps->disc_pid, ps->cred, ps->secid);  		}  	}  } -#ifdef CONFIG_USB_DEVICE_CLASS -static struct class *usb_classdev_class; - -static int usb_classdev_add(struct usb_device *dev) -{ -	struct device *cldev; - -	cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt, -			      NULL, "usbdev%d.%d", dev->bus->busnum, -			      dev->devnum); -	if (IS_ERR(cldev)) -		return PTR_ERR(cldev); -	dev->usb_classdev = cldev; -	return 0; -} - -static void usb_classdev_remove(struct usb_device *dev) -{ -	if (dev->usb_classdev) -		device_unregister(dev->usb_classdev); -} - -#else -#define usb_classdev_add(dev)		0 -#define usb_classdev_remove(dev)	do {} while (0) - -#endif -  static int usbdev_notify(struct notifier_block *self,  			       unsigned long action, void *dev)  {  	switch (action) {  	case USB_DEVICE_ADD: -		if (usb_classdev_add(dev)) -			return NOTIFY_BAD;  		break;  	case USB_DEVICE_REMOVE: -		usb_classdev_remove(dev);  		usbdev_remove(dev);  		break;  	} @@ -2056,21 +2417,6 @@ int __init usb_devio_init(void)  		       USB_DEVICE_MAJOR);  		goto error_cdev;  	} -#ifdef CONFIG_USB_DEVICE_CLASS -	usb_classdev_class = class_create(THIS_MODULE, "usb_device"); -	if (IS_ERR(usb_classdev_class)) { -		printk(KERN_ERR "Unable to register usb_device class\n"); -		retval = PTR_ERR(usb_classdev_class); -		cdev_del(&usb_device_cdev); -		usb_classdev_class = NULL; -		goto out; -	} -	/* devices of this class shadow the major:minor of their parent -	 * device, so clear ->dev_kobj to prevent adding duplicate entries -	 * to /sys/dev -	 */ -	usb_classdev_class->dev_kobj = NULL; -#endif  	usb_register_notify(&usbdev_nb);  out:  	return retval; @@ -2083,9 +2429,6 @@ error_cdev:  void usb_devio_cleanup(void)  {  	usb_unregister_notify(&usbdev_nb); -#ifdef CONFIG_USB_DEVICE_CLASS -	class_destroy(usb_classdev_class); -#endif  	cdev_del(&usb_device_cdev);  	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);  } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb04..4aeb10034de 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -24,31 +24,33 @@  #include <linux/device.h>  #include <linux/slab.h> +#include <linux/export.h>  #include <linux/usb.h>  #include <linux/usb/quirks.h>  #include <linux/usb/hcd.h> -#include <linux/pm_runtime.h>  #include "usb.h" -#ifdef CONFIG_HOTPLUG -  /*   * Adds a new dynamic USBdevice ID to this driver,   * and cause the driver to probe for all devices again.   */  ssize_t usb_store_new_id(struct usb_dynids *dynids, +			 const struct usb_device_id *id_table,  			 struct device_driver *driver,  			 const char *buf, size_t count)  {  	struct usb_dynid *dynid;  	u32 idVendor = 0;  	u32 idProduct = 0; +	unsigned int bInterfaceClass = 0; +	u32 refVendor, refProduct;  	int fields = 0;  	int retval = 0; -	fields = sscanf(buf, "%x %x", &idVendor, &idProduct); +	fields = sscanf(buf, "%x %x %x %x %x", &idVendor, &idProduct, +			&bInterfaceClass, &refVendor, &refProduct);  	if (fields < 2)  		return -EINVAL; @@ -60,48 +62,96 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,  	dynid->id.idVendor = idVendor;  	dynid->id.idProduct = idProduct;  	dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; +	if (fields > 2 && bInterfaceClass) { +		if (bInterfaceClass > 255) { +			retval = -EINVAL; +			goto fail; +		} + +		dynid->id.bInterfaceClass = (u8)bInterfaceClass; +		dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; +	} + +	if (fields > 4) { +		const struct usb_device_id *id = id_table; + +		if (!id) { +			retval = -ENODEV; +			goto fail; +		} + +		for (; id->match_flags; id++) +			if (id->idVendor == refVendor && id->idProduct == refProduct) +				break; + +		if (id->match_flags) { +			dynid->id.driver_info = id->driver_info; +		} else { +			retval = -ENODEV; +			goto fail; +		} +	}  	spin_lock(&dynids->lock);  	list_add_tail(&dynid->node, &dynids->list);  	spin_unlock(&dynids->lock); -	if (get_driver(driver)) { -		retval = driver_attach(driver); -		put_driver(driver); -	} +	retval = driver_attach(driver);  	if (retval)  		return retval;  	return count; + +fail: +	kfree(dynid); +	return retval;  }  EXPORT_SYMBOL_GPL(usb_store_new_id); -static ssize_t store_new_id(struct device_driver *driver, +ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf) +{ +	struct usb_dynid *dynid; +	size_t count = 0; + +	list_for_each_entry(dynid, &dynids->list, node) +		if (dynid->id.bInterfaceClass != 0) +			count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x %02x\n", +					   dynid->id.idVendor, dynid->id.idProduct, +					   dynid->id.bInterfaceClass); +		else +			count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x\n", +					   dynid->id.idVendor, dynid->id.idProduct); +	return count; +} +EXPORT_SYMBOL_GPL(usb_show_dynids); + +static ssize_t new_id_show(struct device_driver *driver, char *buf) +{ +	struct usb_driver *usb_drv = to_usb_driver(driver); + +	return usb_show_dynids(&usb_drv->dynids, buf); +} + +static ssize_t new_id_store(struct device_driver *driver,  			    const char *buf, size_t count)  {  	struct usb_driver *usb_drv = to_usb_driver(driver); -	return usb_store_new_id(&usb_drv->dynids, driver, buf, count); +	return usb_store_new_id(&usb_drv->dynids, usb_drv->id_table, driver, buf, count);  } -static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); +static DRIVER_ATTR_RW(new_id); -/** - * store_remove_id - remove a USB device ID from this driver - * @driver: target device driver - * @buf: buffer for scanning device ID data - * @count: input size - * - * Removes a dynamic usb device ID from this driver. +/* + * Remove a USB device ID from this driver   */ -static ssize_t -store_remove_id(struct device_driver *driver, const char *buf, size_t count) +static ssize_t remove_id_store(struct device_driver *driver, const char *buf, +			       size_t count)  {  	struct usb_dynid *dynid, *n;  	struct usb_driver *usb_driver = to_usb_driver(driver); -	u32 idVendor = 0; -	u32 idProduct = 0; -	int fields = 0; -	int retval = 0; +	u32 idVendor; +	u32 idProduct; +	int fields;  	fields = sscanf(buf, "%x %x", &idVendor, &idProduct);  	if (fields < 2) @@ -114,55 +164,52 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)  		    (id->idProduct == idProduct)) {  			list_del(&dynid->node);  			kfree(dynid); -			retval = 0;  			break;  		}  	}  	spin_unlock(&usb_driver->dynids.lock); - -	if (retval) -		return retval;  	return count;  } -static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static int usb_create_newid_file(struct usb_driver *usb_drv) +static ssize_t remove_id_show(struct device_driver *driver, char *buf) +{ +	return new_id_show(driver, buf); +} +static DRIVER_ATTR_RW(remove_id); + +static int usb_create_newid_files(struct usb_driver *usb_drv)  {  	int error = 0;  	if (usb_drv->no_dynamic_id)  		goto exit; -	if (usb_drv->probe != NULL) +	if (usb_drv->probe != NULL) {  		error = driver_create_file(&usb_drv->drvwrap.driver,  					   &driver_attr_new_id); +		if (error == 0) { +			error = driver_create_file(&usb_drv->drvwrap.driver, +					&driver_attr_remove_id); +			if (error) +				driver_remove_file(&usb_drv->drvwrap.driver, +						&driver_attr_new_id); +		} +	}  exit:  	return error;  } -static void usb_remove_newid_file(struct usb_driver *usb_drv) +static void usb_remove_newid_files(struct usb_driver *usb_drv)  {  	if (usb_drv->no_dynamic_id)  		return; -	if (usb_drv->probe != NULL) +	if (usb_drv->probe != NULL) {  		driver_remove_file(&usb_drv->drvwrap.driver, -				   &driver_attr_new_id); -} - -static int -usb_create_removeid_file(struct usb_driver *drv) -{ -	int error = 0; -	if (drv->probe != NULL) -		error = driver_create_file(&drv->drvwrap.driver,  				&driver_attr_remove_id); -	return error; -} - -static void usb_remove_removeid_file(struct usb_driver *drv) -{ -	driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); +		driver_remove_file(&usb_drv->drvwrap.driver, +				   &driver_attr_new_id); +	}  }  static void usb_free_dynids(struct usb_driver *usb_drv) @@ -176,30 +223,6 @@ static void usb_free_dynids(struct usb_driver *usb_drv)  	}  	spin_unlock(&usb_drv->dynids.lock);  } -#else -static inline int usb_create_newid_file(struct usb_driver *usb_drv) -{ -	return 0; -} - -static void usb_remove_newid_file(struct usb_driver *usb_drv) -{ -} - -static int -usb_create_removeid_file(struct usb_driver *drv) -{ -	return 0; -} - -static void usb_remove_removeid_file(struct usb_driver *drv) -{ -} - -static inline void usb_free_dynids(struct usb_driver *usb_drv) -{ -} -#endif  static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,  							struct usb_driver *drv) @@ -230,7 +253,7 @@ static int usb_probe_device(struct device *dev)  	/* TODO: Add real matching code */  	/* The device should always appear to be in use -	 * unless the driver suports autosuspend. +	 * unless the driver supports autosuspend.  	 */  	if (!udriver->supports_autosuspend)  		error = usb_autoresume_device(udev); @@ -275,6 +298,7 @@ static int usb_probe_interface(struct device *dev)  	struct usb_device *udev = interface_to_usbdev(intf);  	const struct usb_device_id *id;  	int error = -ENODEV; +	int lpm_disable_error;  	dev_dbg(dev, "%s\n", __func__); @@ -288,9 +312,9 @@ static int usb_probe_interface(struct device *dev)  		return error;  	} -	id = usb_match_id(intf, driver->id_table); +	id = usb_match_dynamic_id(intf, driver);  	if (!id) -		id = usb_match_dynamic_id(intf, driver); +		id = usb_match_id(intf, driver->id_table);  	if (!id)  		return error; @@ -311,6 +335,25 @@ static int usb_probe_interface(struct device *dev)  	if (driver->supports_autosuspend)  		pm_runtime_enable(dev); +	/* If the new driver doesn't allow hub-initiated LPM, and we can't +	 * disable hub-initiated LPM, then fail the probe. +	 * +	 * Otherwise, leaving LPM enabled should be harmless, because the +	 * endpoint intervals should remain the same, and the U1/U2 timeouts +	 * should remain the same. +	 * +	 * If we need to install alt setting 0 before probe, or another alt +	 * setting during probe, that should also be fine.  usb_set_interface() +	 * will attempt to disable LPM, and fail if it can't disable it. +	 */ +	lpm_disable_error = usb_unlocked_disable_lpm(udev); +	if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +		dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.", +				__func__, driver->name); +		error = lpm_disable_error; +		goto err; +	} +  	/* Carry out a deferred switch to altsetting 0 */  	if (intf->needs_altsetting0) {  		error = usb_set_interface(udev, intf->altsetting[0]. @@ -325,14 +368,24 @@ static int usb_probe_interface(struct device *dev)  		goto err;  	intf->condition = USB_INTERFACE_BOUND; + +	/* If the LPM disable succeeded, balance the ref counts. */ +	if (!lpm_disable_error) +		usb_unlocked_enable_lpm(udev); +  	usb_autosuspend_device(udev);  	return error;   err: +	usb_set_intfdata(intf, NULL);  	intf->needs_remote_wakeup = 0;  	intf->condition = USB_INTERFACE_UNBOUND;  	usb_cancel_queued_reset(intf); +	/* If the LPM disable succeeded, balance the ref counts. */ +	if (!lpm_disable_error) +		usb_unlocked_enable_lpm(udev); +  	/* Unbound interfaces are always runtime-PM-disabled and -suspended */  	if (driver->supports_autosuspend)  		pm_runtime_disable(dev); @@ -347,8 +400,9 @@ static int usb_unbind_interface(struct device *dev)  {  	struct usb_driver *driver = to_usb_driver(dev->driver);  	struct usb_interface *intf = to_usb_interface(dev); +	struct usb_host_endpoint *ep, **eps = NULL;  	struct usb_device *udev; -	int error, r; +	int i, j, error, r, lpm_disable_error;  	intf->condition = USB_INTERFACE_UNBINDING; @@ -356,6 +410,13 @@ static int usb_unbind_interface(struct device *dev)  	udev = interface_to_usbdev(intf);  	error = usb_autoresume_device(udev); +	/* Hub-initiated LPM policy may change, so attempt to disable LPM until +	 * the driver is unbound.  If LPM isn't disabled, that's fine because it +	 * wouldn't be enabled unless all the bound interfaces supported +	 * hub-initiated LPM. +	 */ +	lpm_disable_error = usb_unlocked_disable_lpm(udev); +  	/* Terminate all URBs for this interface unless the driver  	 * supports "soft" unbinding.  	 */ @@ -365,6 +426,26 @@ static int usb_unbind_interface(struct device *dev)  	driver->disconnect(intf);  	usb_cancel_queued_reset(intf); +	/* Free streams */ +	for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { +		ep = &intf->cur_altsetting->endpoint[i]; +		if (ep->streams == 0) +			continue; +		if (j == 0) { +			eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *), +				      GFP_KERNEL); +			if (!eps) { +				dev_warn(dev, "oom, leaking streams\n"); +				break; +			} +		} +		eps[j++] = ep; +	} +	if (j) { +		usb_free_streams(intf, eps, j, GFP_KERNEL); +		kfree(eps); +	} +  	/* Reset other interface state.  	 * We cannot do a Set-Interface if the device is suspended or  	 * if it is prepared for a system sleep (since installing a new @@ -376,7 +457,7 @@ static int usb_unbind_interface(struct device *dev)  		 * Just re-enable it without affecting the endpoint toggles.  		 */  		usb_enable_interface(udev, intf, false); -	} else if (!error && intf->dev.power.status == DPM_ON) { +	} else if (!error && !intf->dev.power.is_prepared) {  		r = usb_set_interface(udev, intf->altsetting[0].  				desc.bInterfaceNumber, 0);  		if (r < 0) @@ -389,6 +470,10 @@ static int usb_unbind_interface(struct device *dev)  	intf->condition = USB_INTERFACE_UNBOUND;  	intf->needs_remote_wakeup = 0; +	/* Attempt to re-enable USB3 LPM, if the disable succeeded. */ +	if (!lpm_disable_error) +		usb_unlocked_enable_lpm(udev); +  	/* Unbound interfaces are always runtime-PM-disabled and -suspended */  	if (driver->supports_autosuspend)  		pm_runtime_disable(dev); @@ -424,22 +509,36 @@ static int usb_unbind_interface(struct device *dev)   * Callers must own the device lock, so driver probe() entries don't need   * extra locking, but other call contexts may need to explicitly claim that   * lock. + * + * Return: 0 on success.   */  int usb_driver_claim_interface(struct usb_driver *driver,  				struct usb_interface *iface, void *priv)  {  	struct device *dev = &iface->dev; +	struct usb_device *udev;  	int retval = 0; +	int lpm_disable_error;  	if (dev->driver)  		return -EBUSY; +	udev = interface_to_usbdev(iface); +  	dev->driver = &driver->drvwrap.driver;  	usb_set_intfdata(iface, priv);  	iface->needs_binding = 0;  	iface->condition = USB_INTERFACE_BOUND; +	/* Disable LPM until this driver is bound. */ +	lpm_disable_error = usb_unlocked_disable_lpm(udev); +	if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +		dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", +				__func__, driver->name); +		return -ENOMEM; +	} +  	/* Claimed interfaces are initially inactive (suspended) and  	 * runtime-PM-enabled, but only if the driver has autosuspend  	 * support.  Otherwise they are marked active, to prevent the @@ -458,6 +557,10 @@ int usb_driver_claim_interface(struct usb_driver *driver,  	if (device_is_registered(dev))  		retval = device_bind_driver(dev); +	/* Attempt to re-enable USB3 LPM, if the disable was successful. */ +	if (!lpm_disable_error) +		usb_unlocked_enable_lpm(udev); +  	return retval;  }  EXPORT_SYMBOL_GPL(usb_driver_claim_interface); @@ -541,30 +644,19 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)  }  /* returns 0 if no match, 1 if match */ -int usb_match_one_id(struct usb_interface *interface, -		     const struct usb_device_id *id) +int usb_match_one_id_intf(struct usb_device *dev, +			  struct usb_host_interface *intf, +			  const struct usb_device_id *id)  { -	struct usb_host_interface *intf; -	struct usb_device *dev; - -	/* proc_connectinfo in devio.c may call us with id == NULL. */ -	if (id == NULL) -		return 0; - -	intf = interface->cur_altsetting; -	dev = interface_to_usbdev(interface); - -	if (!usb_match_device(dev, id)) -		return 0; - -	/* The interface class, subclass, and protocol should never be +	/* The interface class, subclass, protocol and number should never be  	 * checked for a match if the device class is Vendor Specific,  	 * unless the match record specifies the Vendor ID. */  	if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&  			!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&  			(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |  				USB_DEVICE_ID_MATCH_INT_SUBCLASS | -				USB_DEVICE_ID_MATCH_INT_PROTOCOL))) +				USB_DEVICE_ID_MATCH_INT_PROTOCOL | +				USB_DEVICE_ID_MATCH_INT_NUMBER)))  		return 0;  	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && @@ -579,8 +671,32 @@ int usb_match_one_id(struct usb_interface *interface,  	    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))  		return 0; +	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) && +	    (id->bInterfaceNumber != intf->desc.bInterfaceNumber)) +		return 0; +  	return 1;  } + +/* returns 0 if no match, 1 if match */ +int usb_match_one_id(struct usb_interface *interface, +		     const struct usb_device_id *id) +{ +	struct usb_host_interface *intf; +	struct usb_device *dev; + +	/* proc_connectinfo in devio.c may call us with id == NULL. */ +	if (id == NULL) +		return 0; + +	intf = interface->cur_altsetting; +	dev = interface_to_usbdev(interface); + +	if (!usb_match_device(dev, id)) +		return 0; + +	return usb_match_one_id_intf(dev, intf, id); +}  EXPORT_SYMBOL_GPL(usb_match_one_id);  /** @@ -596,6 +712,8 @@ EXPORT_SYMBOL_GPL(usb_match_one_id);   * These device tables are exported with MODULE_DEVICE_TABLE, through   * modutils, to support the driver loading functionality of USB hotplugging.   * + * Return: The first matching usb_device_id, or %NULL. + *   * What Matches:   *   * The "match_flags" element in a usb_device_id controls which @@ -712,7 +830,6 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)  	return 0;  } -#ifdef	CONFIG_HOTPLUG  static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)  {  	struct usb_device *usb_dev; @@ -737,16 +854,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)  		return -ENODEV;  	} -#ifdef	CONFIG_USB_DEVICEFS -	/* If this is available, userspace programs can directly read -	 * all the device descriptors we don't tell them about.  Or -	 * act as usermode drivers. -	 */ -	if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", -			   usb_dev->bus->busnum, usb_dev->devnum)) -		return -ENOMEM; -#endif -  	/* per-device configurations are common */  	if (add_uevent_var(env, "PRODUCT=%x/%x/%x",  			   le16_to_cpu(usb_dev->descriptor.idVendor), @@ -764,14 +871,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)  	return 0;  } -#else - -static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) -{ -	return -ENODEV; -} -#endif	/* CONFIG_HOTPLUG */ -  /**   * usb_register_device_driver - register a USB device (not interface) driver   * @new_udriver: USB operations for the device driver @@ -780,7 +879,8 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)   * Registers a USB device driver with the USB core.  The list of   * unattached devices will be rescanned whenever a new driver is   * added, allowing the new driver to attach to any recognized devices. - * Returns a negative error code on failure and 0 on success. + * + * Return: A negative error code on failure and 0 on success.   */  int usb_register_device_driver(struct usb_device_driver *new_udriver,  		struct module *owner) @@ -791,7 +891,7 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver,  		return -ENODEV;  	new_udriver->drvwrap.for_devices = 1; -	new_udriver->drvwrap.driver.name = (char *) new_udriver->name; +	new_udriver->drvwrap.driver.name = new_udriver->name;  	new_udriver->drvwrap.driver.bus = &usb_bus_type;  	new_udriver->drvwrap.driver.probe = usb_probe_device;  	new_udriver->drvwrap.driver.remove = usb_unbind_device; @@ -799,15 +899,13 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver,  	retval = driver_register(&new_udriver->drvwrap.driver); -	if (!retval) { +	if (!retval)  		pr_info("%s: registered new device driver %s\n",  			usbcore_name, new_udriver->name); -		usbfs_update_special(); -	} else { +	else  		printk(KERN_ERR "%s: error %d registering device "  			"	driver %s\n",  			usbcore_name, retval, new_udriver->name); -	}  	return retval;  } @@ -826,7 +924,6 @@ void usb_deregister_device_driver(struct usb_device_driver *udriver)  			usbcore_name, udriver->name);  	driver_unregister(&udriver->drvwrap.driver); -	usbfs_update_special();  }  EXPORT_SYMBOL_GPL(usb_deregister_device_driver); @@ -839,7 +936,8 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);   * Registers a USB interface driver with the USB core.  The list of   * unattached interfaces will be rescanned whenever a new driver is   * added, allowing the new driver to attach to any recognized interfaces. - * Returns a negative error code on failure and 0 on success. + * + * Return: A negative error code on failure and 0 on success.   *   * NOTE: if you want your driver to use the USB major number, you must call   * usb_register_dev() to enable that functionality.  This function no longer @@ -854,7 +952,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,  		return -ENODEV;  	new_driver->drvwrap.for_devices = 0; -	new_driver->drvwrap.driver.name = (char *) new_driver->name; +	new_driver->drvwrap.driver.name = new_driver->name;  	new_driver->drvwrap.driver.bus = &usb_bus_type;  	new_driver->drvwrap.driver.probe = usb_probe_interface;  	new_driver->drvwrap.driver.remove = usb_unbind_interface; @@ -867,24 +965,16 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,  	if (retval)  		goto out; -	usbfs_update_special(); - -	retval = usb_create_newid_file(new_driver); +	retval = usb_create_newid_files(new_driver);  	if (retval)  		goto out_newid; -	retval = usb_create_removeid_file(new_driver); -	if (retval) -		goto out_removeid; -  	pr_info("%s: registered new interface driver %s\n",  			usbcore_name, new_driver->name);  out:  	return retval; -out_removeid: -	usb_remove_newid_file(new_driver);  out_newid:  	driver_unregister(&new_driver->drvwrap.driver); @@ -911,12 +1001,9 @@ void usb_deregister(struct usb_driver *driver)  	pr_info("%s: deregistering interface driver %s\n",  			usbcore_name, driver->name); -	usb_remove_removeid_file(driver); -	usb_remove_newid_file(driver); -	usb_free_dynids(driver); +	usb_remove_newid_files(driver);  	driver_unregister(&driver->drvwrap.driver); - -	usbfs_update_special(); +	usb_free_dynids(driver);  }  EXPORT_SYMBOL_GPL(usb_deregister); @@ -924,8 +1011,7 @@ EXPORT_SYMBOL_GPL(usb_deregister);   * it doesn't support pre_reset/post_reset/reset_resume or   * because it doesn't support suspend/resume.   * - * The caller must hold @intf's device's lock, but not its pm_mutex - * and not @intf->dev.sem. + * The caller must hold @intf's device's lock, but not @intf's lock.   */  void usb_forced_unbind_intf(struct usb_interface *intf)  { @@ -938,30 +1024,46 @@ void usb_forced_unbind_intf(struct usb_interface *intf)  	intf->needs_binding = 1;  } +/* + * Unbind drivers for @udev's marked interfaces.  These interfaces have + * the needs_binding flag set, for example by usb_resume_interface(). + * + * The caller must hold @udev's device lock. + */ +static void unbind_marked_interfaces(struct usb_device *udev) +{ +	struct usb_host_config	*config; +	int			i; +	struct usb_interface	*intf; + +	config = udev->actconfig; +	if (config) { +		for (i = 0; i < config->desc.bNumInterfaces; ++i) { +			intf = config->interface[i]; +			if (intf->dev.driver && intf->needs_binding) +				usb_forced_unbind_intf(intf); +		} +	} +} +  /* Delayed forced unbinding of a USB interface driver and scan   * for rebinding.   * - * The caller must hold @intf's device's lock, but not its pm_mutex - * and not @intf->dev.sem. + * The caller must hold @intf's device's lock, but not @intf's lock.   *   * Note: Rebinds will be skipped if a system sleep transition is in   * progress and the PM "complete" callback hasn't occurred yet.   */ -void usb_rebind_intf(struct usb_interface *intf) +static void usb_rebind_intf(struct usb_interface *intf)  {  	int rc;  	/* Delayed unbind of an existing driver */ -	if (intf->dev.driver) { -		struct usb_driver *driver = -				to_usb_driver(intf->dev.driver); - -		dev_dbg(&intf->dev, "forced unbind\n"); -		usb_driver_release_interface(driver, intf); -	} +	if (intf->dev.driver) +		usb_forced_unbind_intf(intf);  	/* Try to rebind the interface */ -	if (intf->dev.power.status == DPM_ON) { +	if (!intf->dev.power.is_prepared) {  		intf->needs_binding = 0;  		rc = device_attach(&intf->dev);  		if (rc < 0) @@ -969,17 +1071,50 @@ void usb_rebind_intf(struct usb_interface *intf)  	}  } -#ifdef CONFIG_PM +/* + * Rebind drivers to @udev's marked interfaces.  These interfaces have + * the needs_binding flag set. + * + * The caller must hold @udev's device lock. + */ +static void rebind_marked_interfaces(struct usb_device *udev) +{ +	struct usb_host_config	*config; +	int			i; +	struct usb_interface	*intf; + +	config = udev->actconfig; +	if (config) { +		for (i = 0; i < config->desc.bNumInterfaces; ++i) { +			intf = config->interface[i]; +			if (intf->needs_binding) +				usb_rebind_intf(intf); +		} +	} +} -#define DO_UNBIND	0 -#define DO_REBIND	1 +/* + * Unbind all of @udev's marked interfaces and then rebind all of them. + * This ordering is necessary because some drivers claim several interfaces + * when they are first probed. + * + * The caller must hold @udev's device lock. + */ +void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev) +{ +	unbind_marked_interfaces(udev); +	rebind_marked_interfaces(udev); +} + +#ifdef CONFIG_PM -/* Unbind drivers for @udev's interfaces that don't support suspend/resume, - * or rebind interfaces that have been unbound, according to @action. +/* Unbind drivers for @udev's interfaces that don't support suspend/resume + * There is no check for reset_resume here because it can be determined + * only during resume whether reset_resume is needed.   *   * The caller must hold @udev's device lock.   */ -static void do_unbind_rebind(struct usb_device *udev, int action) +static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)  {  	struct usb_host_config	*config;  	int			i; @@ -990,18 +1125,11 @@ static void do_unbind_rebind(struct usb_device *udev, int action)  	if (config) {  		for (i = 0; i < config->desc.bNumInterfaces; ++i) {  			intf = config->interface[i]; -			switch (action) { -			case DO_UNBIND: -				if (intf->dev.driver) { -					drv = to_usb_driver(intf->dev.driver); -					if (!drv->suspend || !drv->resume) -						usb_forced_unbind_intf(intf); -				} -				break; -			case DO_REBIND: -				if (intf->needs_binding) -					usb_rebind_intf(intf); -				break; + +			if (intf->dev.driver) { +				drv = to_usb_driver(intf->dev.driver); +				if (!drv->suspend || !drv->resume) +					usb_forced_unbind_intf(intf);  			}  		}  	} @@ -1047,8 +1175,7 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg)  	/* Non-root devices on a full/low-speed bus must wait for their  	 * companion high-speed root hub, in case a handoff is needed.  	 */ -	if (!(msg.event & PM_EVENT_AUTO) && udev->parent && -			udev->bus->hs_companion) +	if (!PMSG_IS_AUTO(msg) && udev->parent && udev->bus->hs_companion)  		device_pm_wait_for_dev(&udev->dev,  				&udev->bus->hs_companion->root_hub->dev); @@ -1074,17 +1201,10 @@ static int usb_suspend_interface(struct usb_device *udev,  		goto done;  	driver = to_usb_driver(intf->dev.driver); -	if (driver->suspend) { -		status = driver->suspend(intf, msg); -		if (status && !(msg.event & PM_EVENT_AUTO)) -			dev_err(&intf->dev, "%s error %d\n", -					"suspend", status); -	} else { -		/* Later we will unbind the driver and reprobe */ -		intf->needs_binding = 1; -		dev_warn(&intf->dev, "no %s for driver %s?\n", -				"suspend", driver->name); -	} +	/* at this time we know the driver supports suspend */ +	status = driver->suspend(intf, msg); +	if (status && !PMSG_IS_AUTO(msg)) +		dev_err(&intf->dev, "suspend error %d\n", status);   done:  	dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); @@ -1108,8 +1228,7 @@ static int usb_resume_interface(struct usb_device *udev,  	if (intf->condition == USB_INTERFACE_UNBOUND) {  		/* Carry out a deferred switch to altsetting 0 */ -		if (intf->needs_altsetting0 && -				intf->dev.power.status == DPM_ON) { +		if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) {  			usb_set_interface(udev, intf->altsetting[0].  					desc.bInterfaceNumber, 0);  			intf->needs_altsetting0 = 0; @@ -1130,20 +1249,13 @@ static int usb_resume_interface(struct usb_device *udev,  						"reset_resume", status);  		} else {  			intf->needs_binding = 1; -			dev_warn(&intf->dev, "no %s for driver %s?\n", -					"reset_resume", driver->name); +			dev_dbg(&intf->dev, "no reset_resume for driver %s?\n", +					driver->name);  		}  	} else { -		if (driver->resume) { -			status = driver->resume(intf); -			if (status) -				dev_err(&intf->dev, "%s error %d\n", -						"resume", status); -		} else { -			intf->needs_binding = 1; -			dev_warn(&intf->dev, "no %s for driver %s?\n", -					"resume", driver->name); -		} +		status = driver->resume(intf); +		if (status) +			dev_err(&intf->dev, "resume error %d\n", status);  	}  done: @@ -1160,9 +1272,14 @@ done:   *   * This is the central routine for suspending USB devices.  It calls the   * suspend methods for all the interface drivers in @udev and then calls - * the suspend method for @udev itself.  If an error occurs at any stage, - * all the interfaces which were suspended are resumed so that they remain - * in the same state as the device. + * the suspend method for @udev itself.  When the routine is called in + * autosuspend, if an error occurs at any stage, all the interfaces + * which were suspended are resumed so that they remain in the same + * state as the device, but when called from system sleep, all error + * from suspend methods of interfaces and the non-root-hub device itself + * are simply ignored, so all suspended interfaces are only resumed + * to the device's state when @udev is root-hub and its suspend method + * returns failure.   *   * Autosuspend requests originating from a child device or an interface   * driver may be made without the protection of @udev's device lock, but @@ -1172,6 +1289,8 @@ done:   * unpredictable times.   *   * This routine can run only in process context. + * + * Return: 0 if the suspend succeeded.   */  static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)  { @@ -1189,19 +1308,35 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)  		for (i = n - 1; i >= 0; --i) {  			intf = udev->actconfig->interface[i];  			status = usb_suspend_interface(udev, intf, msg); + +			/* Ignore errors during system sleep transitions */ +			if (!PMSG_IS_AUTO(msg)) +				status = 0;  			if (status != 0)  				break;  		}  	} -	if (status == 0) +	if (status == 0) {  		status = usb_suspend_device(udev, msg); +		/* +		 * Ignore errors from non-root-hub devices during +		 * system sleep transitions.  For the most part, +		 * these devices should go to low power anyway when +		 * the entire bus is suspended. +		 */ +		if (udev->parent && !PMSG_IS_AUTO(msg)) +			status = 0; +	} +  	/* If the suspend failed, resume interfaces that did get suspended */  	if (status != 0) { -		msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); -		while (++i < n) { -			intf = udev->actconfig->interface[i]; -			usb_resume_interface(udev, intf, msg, 0); +		if (udev->actconfig) { +			msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); +			while (++i < n) { +				intf = udev->actconfig->interface[i]; +				usb_resume_interface(udev, intf, msg, 0); +			}  		}  	/* If the suspend succeeded then prevent any more URB submissions @@ -1237,6 +1372,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)   * unpredictable times.   *   * This routine can run only in process context. + * + * Return: 0 on success.   */  static int usb_resume_both(struct usb_device *udev, pm_message_t msg)  { @@ -1262,6 +1399,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)  					udev->reset_resume);  		}  	} +	usb_mark_last_busy(udev);   done:  	dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); @@ -1302,36 +1440,48 @@ int usb_suspend(struct device *dev, pm_message_t msg)  {  	struct usb_device	*udev = to_usb_device(dev); -	do_unbind_rebind(udev, DO_UNBIND); +	unbind_no_pm_drivers_interfaces(udev); + +	/* From now on we are sure all drivers support suspend/resume +	 * but not necessarily reset_resume() +	 * so we may still need to unbind and rebind upon resume +	 */  	choose_wakeup(udev, msg);  	return usb_suspend_both(udev, msg);  }  /* The device lock is held by the PM core */ +int usb_resume_complete(struct device *dev) +{ +	struct usb_device *udev = to_usb_device(dev); + +	/* For PM complete calls, all we do is rebind interfaces +	 * whose needs_binding flag is set +	 */ +	if (udev->state != USB_STATE_NOTATTACHED) +		rebind_marked_interfaces(udev); +	return 0; +} + +/* The device lock is held by the PM core */  int usb_resume(struct device *dev, pm_message_t msg)  {  	struct usb_device	*udev = to_usb_device(dev);  	int			status; -	/* For PM complete calls, all we do is rebind interfaces */ -	if (msg.event == PM_EVENT_ON) { -		if (udev->state != USB_STATE_NOTATTACHED) -			do_unbind_rebind(udev, DO_REBIND); -		status = 0; - -	/* For all other calls, take the device back to full power and +	/* For all calls, take the device back to full power and  	 * tell the PM core in case it was autosuspended previously. -	 * Unbind the interfaces that will need rebinding later. +	 * Unbind the interfaces that will need rebinding later, +	 * because they fail to support reset_resume. +	 * (This can't be done in usb_resume_interface() +	 * above because it doesn't own the right set of locks.)  	 */ -	} else { -		status = usb_resume_both(udev, msg); -		if (status == 0) { -			pm_runtime_disable(dev); -			pm_runtime_set_active(dev); -			pm_runtime_enable(dev); -			udev->last_busy = jiffies; -			do_unbind_rebind(udev, DO_REBIND); -		} +	status = usb_resume_both(udev, msg); +	if (status == 0) { +		pm_runtime_disable(dev); +		pm_runtime_set_active(dev); +		pm_runtime_enable(dev); +		unbind_marked_interfaces(udev);  	}  	/* Avoid PM error messages for devices disconnected while suspended @@ -1344,7 +1494,7 @@ int usb_resume(struct device *dev, pm_message_t msg)  #endif /* CONFIG_PM */ -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME  /**   * usb_enable_autosuspend - allow a USB device to be autosuspended @@ -1397,33 +1547,8 @@ void usb_autosuspend_device(struct usb_device *udev)  {  	int	status; -	udev->last_busy = jiffies; -	status = pm_runtime_put_sync(&udev->dev); -	dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", -			__func__, atomic_read(&udev->dev.power.usage_count), -			status); -} - -/** - * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces - * @udev: the usb_device to autosuspend - * - * This routine should be called when a core subsystem thinks @udev may - * be ready to autosuspend. - * - * @udev's usage counter left unchanged.  If it is 0 and all the interfaces - * are inactive then an autosuspend will be attempted.  The attempt may - * fail or be delayed. - * - * The caller must hold @udev's device lock. - * - * This routine can run only in process context. - */ -void usb_try_autosuspend_device(struct usb_device *udev) -{ -	int	status; - -	status = pm_runtime_idle(&udev->dev); +	usb_mark_last_busy(udev); +	status = pm_runtime_put_sync_autosuspend(&udev->dev);  	dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",  			__func__, atomic_read(&udev->dev.power.usage_count),  			status); @@ -1446,6 +1571,8 @@ void usb_try_autosuspend_device(struct usb_device *udev)   * The caller must hold @udev's device lock.   *   * This routine can run only in process context. + * + * Return: 0 on success. A negative error code otherwise.   */  int usb_autoresume_device(struct usb_device *udev)  { @@ -1482,7 +1609,7 @@ void usb_autopm_put_interface(struct usb_interface *intf)  	struct usb_device	*udev = interface_to_usbdev(intf);  	int			status; -	udev->last_busy = jiffies; +	usb_mark_last_busy(udev);  	atomic_dec(&intf->pm_usage_cnt);  	status = pm_runtime_put_sync(&intf->dev);  	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", @@ -1509,32 +1636,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface);  void usb_autopm_put_interface_async(struct usb_interface *intf)  {  	struct usb_device	*udev = interface_to_usbdev(intf); -	unsigned long		last_busy; -	int			status = 0; +	int			status; -	last_busy = udev->last_busy; -	udev->last_busy = jiffies; +	usb_mark_last_busy(udev);  	atomic_dec(&intf->pm_usage_cnt); -	pm_runtime_put_noidle(&intf->dev); - -	if (udev->dev.power.runtime_auto) { -		/* Optimization: Don't schedule a delayed autosuspend if -		 * the timer is already running and the expiration time -		 * wouldn't change. -		 * -		 * We have to use the interface's timer.  Attempts to -		 * schedule a suspend for the device would fail because -		 * the interface is still active. -		 */ -		if (intf->dev.power.timer_expires == 0 || -				round_jiffies_up(last_busy) != -				round_jiffies_up(jiffies)) { -			status = pm_schedule_suspend(&intf->dev, -					jiffies_to_msecs( -					round_jiffies_up_relative( -						udev->autosuspend_delay))); -		} -	} +	status = pm_runtime_put(&intf->dev);  	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",  			__func__, atomic_read(&intf->dev.power.usage_count),  			status); @@ -1554,7 +1660,7 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf)  {  	struct usb_device	*udev = interface_to_usbdev(intf); -	udev->last_busy = jiffies; +	usb_mark_last_busy(udev);  	atomic_dec(&intf->pm_usage_cnt);  	pm_runtime_put_noidle(&intf->dev);  } @@ -1576,6 +1682,8 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend);   * However if the autoresume fails then the counter is re-decremented.   *   * This routine can run only in process context. + * + * Return: 0 on success.   */  int usb_autopm_get_interface(struct usb_interface *intf)  { @@ -1609,21 +1717,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface);   * resumed.   *   * This routine can run in atomic context. + * + * Return: 0 on success. A negative error code otherwise.   */  int usb_autopm_get_interface_async(struct usb_interface *intf)  { -	int		status = 0; -	enum rpm_status	s; - -	/* Don't request a resume unless the interface is already suspending -	 * or suspended.  Doing so would force a running suspend timer to be -	 * cancelled. -	 */ -	pm_runtime_get_noresume(&intf->dev); -	s = ACCESS_ONCE(intf->dev.power.runtime_status); -	if (s == RPM_SUSPENDING || s == RPM_SUSPENDED) -		status = pm_request_resume(&intf->dev); +	int	status; +	status = pm_runtime_get(&intf->dev);  	if (status < 0 && status != -EINPROGRESS)  		pm_runtime_put_noidle(&intf->dev);  	else @@ -1631,7 +1732,7 @@ int usb_autopm_get_interface_async(struct usb_interface *intf)  	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",  			__func__, atomic_read(&intf->dev.power.usage_count),  			status); -	if (status > 0) +	if (status > 0 || status == -EINPROGRESS)  		status = 0;  	return status;  } @@ -1650,7 +1751,7 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf)  {  	struct usb_device	*udev = interface_to_usbdev(intf); -	udev->last_busy = jiffies; +	usb_mark_last_busy(udev);  	atomic_inc(&intf->pm_usage_cnt);  	pm_runtime_get_noresume(&intf->dev);  } @@ -1661,7 +1762,6 @@ static int autosuspend_check(struct usb_device *udev)  {  	int			w, i;  	struct usb_interface	*intf; -	unsigned long		suspend_time, j;  	/* Fail if autosuspend is disabled, or any interfaces are in use, or  	 * any interface drivers require remote wakeup but it isn't available. @@ -1701,103 +1801,84 @@ static int autosuspend_check(struct usb_device *udev)  		return -EOPNOTSUPP;  	}  	udev->do_remote_wakeup = w; - -	/* If everything is okay but the device hasn't been idle for long -	 * enough, queue a delayed autosuspend request. -	 */ -	j = ACCESS_ONCE(jiffies); -	suspend_time = udev->last_busy + udev->autosuspend_delay; -	if (time_before(j, suspend_time)) { -		pm_schedule_suspend(&udev->dev, jiffies_to_msecs( -				round_jiffies_up_relative(suspend_time - j))); -		return -EAGAIN; -	}  	return 0;  } -static int usb_runtime_suspend(struct device *dev) +int usb_runtime_suspend(struct device *dev)  { -	int	status = 0; +	struct usb_device	*udev = to_usb_device(dev); +	int			status;  	/* A USB device can be suspended if it passes the various autosuspend  	 * checks.  Runtime suspend for a USB device means suspending all the  	 * interfaces and then the device itself.  	 */ -	if (is_usb_device(dev)) { -		struct usb_device	*udev = to_usb_device(dev); - -		if (autosuspend_check(udev) != 0) -			return -EAGAIN; - -		status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); +	if (autosuspend_check(udev) != 0) +		return -EAGAIN; -		/* If an interface fails the suspend, adjust the last_busy -		 * time so that we don't get another suspend attempt right -		 * away. -		 */ -		if (status) { -			udev->last_busy = jiffies + -					(udev->autosuspend_delay == 0 ? -						HZ/2 : 0); -		} +	status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); -		/* Prevent the parent from suspending immediately after */ -		else if (udev->parent) -			udev->parent->last_busy = jiffies; -	} +	/* Allow a retry if autosuspend failed temporarily */ +	if (status == -EAGAIN || status == -EBUSY) +		usb_mark_last_busy(udev); -	/* Runtime suspend for a USB interface doesn't mean anything. */ +	/* +	 * The PM core reacts badly unless the return code is 0, +	 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error +	 * (except for root hubs, because they don't suspend through +	 * an upstream port like other USB devices). +	 */ +	if (status != 0 && udev->parent) +		return -EBUSY;  	return status;  } -static int usb_runtime_resume(struct device *dev) +int usb_runtime_resume(struct device *dev)  { +	struct usb_device	*udev = to_usb_device(dev); +	int			status; +  	/* Runtime resume for a USB device means resuming both the device  	 * and all its interfaces.  	 */ -	if (is_usb_device(dev)) { -		struct usb_device	*udev = to_usb_device(dev); -		int			status; - -		status = usb_resume_both(udev, PMSG_AUTO_RESUME); -		udev->last_busy = jiffies; -		return status; -	} - -	/* Runtime resume for a USB interface doesn't mean anything. */ -	return 0; +	status = usb_resume_both(udev, PMSG_AUTO_RESUME); +	return status;  } -static int usb_runtime_idle(struct device *dev) +int usb_runtime_idle(struct device *dev)  { +	struct usb_device	*udev = to_usb_device(dev); +  	/* An idle USB device can be suspended if it passes the various -	 * autosuspend checks.  An idle interface can be suspended at -	 * any time. +	 * autosuspend checks.  	 */ -	if (is_usb_device(dev)) { -		struct usb_device	*udev = to_usb_device(dev); +	if (autosuspend_check(udev) == 0) +		pm_runtime_autosuspend(dev); +	/* Tell the core not to suspend it, though. */ +	return -EBUSY; +} -		if (autosuspend_check(udev) != 0) -			return 0; +int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); +	int ret = -EPERM; + +	if (enable && !udev->usb2_hw_lpm_allowed) +		return 0; + +	if (hcd->driver->set_usb2_hw_lpm) { +		ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); +		if (!ret) +			udev->usb2_hw_lpm_enabled = enable;  	} -	pm_runtime_suspend(dev); -	return 0; +	return ret;  } -static const struct dev_pm_ops usb_bus_pm_ops = { -	.runtime_suspend =	usb_runtime_suspend, -	.runtime_resume =	usb_runtime_resume, -	.runtime_idle =		usb_runtime_idle, -}; - -#endif /* CONFIG_USB_SUSPEND */ +#endif /* CONFIG_PM_RUNTIME */  struct bus_type usb_bus_type = {  	.name =		"usb",  	.match =	usb_device_match,  	.uevent =	usb_uevent, -#ifdef CONFIG_USB_SUSPEND -	.pm =		&usb_bus_pm_ops, -#endif  }; diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 9da25056302..39a24021fe4 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -12,7 +12,6 @@  #include <linux/kernel.h>  #include <linux/spinlock.h>  #include <linux/slab.h> -#include <linux/idr.h>  #include <linux/usb.h>  #include "usb.h" @@ -24,10 +23,6 @@ struct ep_device {  #define to_ep_device(_dev) \  	container_of(_dev, struct ep_device, dev) -struct device_type usb_ep_device_type = { -	.name =		"usb_endpoint", -}; -  struct ep_attribute {  	struct attribute attr;  	ssize_t (*show)(struct usb_device *, @@ -37,31 +32,31 @@ struct ep_attribute {  	container_of(_attr, struct ep_attribute, attr)  #define usb_ep_attr(field, format_string)			\ -static ssize_t show_ep_##field(struct device *dev,		\ +static ssize_t field##_show(struct device *dev,			\  			       struct device_attribute *attr,	\  			       char *buf)			\  {								\  	struct ep_device *ep = to_ep_device(dev);		\  	return sprintf(buf, format_string, ep->desc->field);	\  }								\ -static DEVICE_ATTR(field, S_IRUGO, show_ep_##field, NULL); +static DEVICE_ATTR_RO(field) -usb_ep_attr(bLength, "%02x\n") -usb_ep_attr(bEndpointAddress, "%02x\n") -usb_ep_attr(bmAttributes, "%02x\n") -usb_ep_attr(bInterval, "%02x\n") +usb_ep_attr(bLength, "%02x\n"); +usb_ep_attr(bEndpointAddress, "%02x\n"); +usb_ep_attr(bmAttributes, "%02x\n"); +usb_ep_attr(bInterval, "%02x\n"); -static ssize_t show_ep_wMaxPacketSize(struct device *dev, -				      struct device_attribute *attr, char *buf) +static ssize_t wMaxPacketSize_show(struct device *dev, +				   struct device_attribute *attr, char *buf)  {  	struct ep_device *ep = to_ep_device(dev);  	return sprintf(buf, "%04x\n", -			le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff); +		        usb_endpoint_maxp(ep->desc) & 0x07ff);  } -static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL); +static DEVICE_ATTR_RO(wMaxPacketSize); -static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, -			    char *buf) +static ssize_t type_show(struct device *dev, struct device_attribute *attr, +			 char *buf)  {  	struct ep_device *ep = to_ep_device(dev);  	char *type = "unknown"; @@ -82,10 +77,10 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,  	}  	return sprintf(buf, "%s\n", type);  } -static DEVICE_ATTR(type, S_IRUGO, show_ep_type, NULL); +static DEVICE_ATTR_RO(type); -static ssize_t show_ep_interval(struct device *dev, -				struct device_attribute *attr, char *buf) +static ssize_t interval_show(struct device *dev, struct device_attribute *attr, +			     char *buf)  {  	struct ep_device *ep = to_ep_device(dev);  	char unit; @@ -128,10 +123,10 @@ static ssize_t show_ep_interval(struct device *dev,  	return sprintf(buf, "%d%cs\n", interval, unit);  } -static DEVICE_ATTR(interval, S_IRUGO, show_ep_interval, NULL); +static DEVICE_ATTR_RO(interval); -static ssize_t show_ep_direction(struct device *dev, -				 struct device_attribute *attr, char *buf) +static ssize_t direction_show(struct device *dev, struct device_attribute *attr, +			      char *buf)  {  	struct ep_device *ep = to_ep_device(dev);  	char *direction; @@ -144,7 +139,7 @@ static ssize_t show_ep_direction(struct device *dev,  		direction = "out";  	return sprintf(buf, "%s\n", direction);  } -static DEVICE_ATTR(direction, S_IRUGO, show_ep_direction, NULL); +static DEVICE_ATTR_RO(direction);  static struct attribute *ep_dev_attrs[] = {  	&dev_attr_bLength.attr, @@ -172,6 +167,11 @@ static void ep_device_release(struct device *dev)  	kfree(ep_dev);  } +struct device_type usb_ep_device_type = { +	.name =		"usb_endpoint", +	.release = ep_device_release, +}; +  int usb_create_ep_devs(struct device *parent,  			struct usb_host_endpoint *endpoint,  			struct usb_device *udev) @@ -190,14 +190,13 @@ int usb_create_ep_devs(struct device *parent,  	ep_dev->dev.groups = ep_dev_groups;  	ep_dev->dev.type = &usb_ep_device_type;  	ep_dev->dev.parent = parent; -	ep_dev->dev.release = ep_device_release;  	dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress); -	device_enable_async_suspend(&ep_dev->dev);  	retval = device_register(&ep_dev->dev);  	if (retval)  		goto error_register; +	device_enable_async_suspend(&ep_dev->dev);  	endpoint->ep_dev = ep_dev;  	return retval; diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 9fe34fb78ef..ea337a718cc 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -8,7 +8,7 @@   * (C) Copyright Deti Fliegl 1999 (new USB architecture)   * (C) Copyright Randy Dunlap 2000   * (C) Copyright David Brownell 2000-2001 (kernel hotplug, usb_device_id, - 	more docs, etc) + *	more docs, etc)   * (C) Copyright Yggdrasil Computing, Inc. 2000   *     (usb_device_id matching changes by Adam J. Richter)   * (C) Copyright Greg Kroah-Hartman 2002-2003 @@ -19,7 +19,6 @@  #include <linux/errno.h>  #include <linux/rwsem.h>  #include <linux/slab.h> -#include <linux/smp_lock.h>  #include <linux/usb.h>  #include "usb.h" @@ -28,29 +27,21 @@  static const struct file_operations *usb_minors[MAX_USB_MINORS];  static DECLARE_RWSEM(minor_rwsem); -static int usb_open(struct inode * inode, struct file * file) +static int usb_open(struct inode *inode, struct file *file)  { -	int minor = iminor(inode); -	const struct file_operations *c;  	int err = -ENODEV; -	const struct file_operations *old_fops, *new_fops = NULL; +	const struct file_operations *new_fops;  	down_read(&minor_rwsem); -	c = usb_minors[minor]; +	new_fops = fops_get(usb_minors[iminor(inode)]); -	if (!c || !(new_fops = fops_get(c))) +	if (!new_fops)  		goto done; -	old_fops = file->f_op; -	file->f_op = new_fops; +	replace_fops(file, new_fops);  	/* Curiouser and curiouser... NULL ->open() as "no device" ? */  	if (file->f_op->open) -		err = file->f_op->open(inode,file); -	if (err) { -		fops_put(file->f_op); -		file->f_op = fops_get(old_fops); -	} -	fops_put(old_fops); +		err = file->f_op->open(inode, file);   done:  	up_read(&minor_rwsem);  	return err; @@ -67,7 +58,7 @@ static struct usb_class {  	struct class *class;  } *usb_class; -static char *usb_devnode(struct device *dev, mode_t *mode) +static char *usb_devnode(struct device *dev, umode_t *mode)  {  	struct usb_class_driver *drv; @@ -93,9 +84,9 @@ static int init_usb_class(void)  	}  	kref_init(&usb_class->kref); -	usb_class->class = class_create(THIS_MODULE, "usb"); +	usb_class->class = class_create(THIS_MODULE, "usbmisc");  	if (IS_ERR(usb_class->class)) { -		result = IS_ERR(usb_class->class); +		result = PTR_ERR(usb_class->class);  		printk(KERN_ERR "class_create failed for usb devices\n");  		kfree(usb_class);  		usb_class = NULL; @@ -154,7 +145,7 @@ void usb_major_cleanup(void)   * usb_deregister_dev() must be called when the driver is done with   * the minor numbers given out by this function.   * - * Returns -EINVAL if something bad happens with trying to register a + * Return: -EINVAL if something bad happens with trying to register a   * device, and 0 on success.   */  int usb_register_dev(struct usb_interface *intf, @@ -167,7 +158,7 @@ int usb_register_dev(struct usb_interface *intf,  	char *temp;  #ifdef CONFIG_USB_DYNAMIC_MINORS -	/*  +	/*  	 * We don't care what the device tries to start at, we want to start  	 * at zero to pack the devices into the smallest available space with  	 * no holes in the minor range. @@ -184,7 +175,7 @@ int usb_register_dev(struct usb_interface *intf,  	if (retval)  		return retval; -	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base); +	dev_dbg(&intf->dev, "looking for a minor, starting at %d\n", minor_base);  	down_write(&minor_rwsem);  	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { @@ -237,23 +228,15 @@ EXPORT_SYMBOL_GPL(usb_register_dev);  void usb_deregister_dev(struct usb_interface *intf,  			struct usb_class_driver *class_driver)  { -	int minor_base = class_driver->minor_base; -	char name[20]; - -#ifdef CONFIG_USB_DYNAMIC_MINORS -	minor_base = 0; -#endif -  	if (intf->minor == -1)  		return; -	dbg ("removing %d minor", intf->minor); +	dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);  	down_write(&minor_rwsem);  	usb_minors[intf->minor] = NULL;  	up_write(&minor_rwsem); -	snprintf(name, sizeof(name), class_driver->name, intf->minor - minor_base);  	device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));  	intf->usb_dev = NULL;  	intf->minor = -1; diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 69ecd3c9231..358ca8dd784 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -47,6 +47,9 @@ int usb_choose_configuration(struct usb_device *udev)  	int insufficient_power = 0;  	struct usb_host_config *c, *best; +	if (usb_device_is_owned(udev)) +		return 0; +  	best = NULL;  	c = udev->config;  	num_configs = udev->descriptor.bNumConfigurations; @@ -97,7 +100,7 @@ int usb_choose_configuration(struct usb_device *udev)  		 */  		/* Rule out configs that draw too much bus current */ -		if (c->desc.bMaxPower * 2 > udev->bus_mA) { +		if (usb_get_max_power(udev, c) > udev->bus_mA) {  			insufficient_power++;  			continue;  		} @@ -152,6 +155,7 @@ int usb_choose_configuration(struct usb_device *udev)  	}  	return i;  } +EXPORT_SYMBOL_GPL(usb_choose_configuration);  static int generic_probe(struct usb_device *udev)  { @@ -160,15 +164,13 @@ static int generic_probe(struct usb_device *udev)  	/* Choose and set the configuration.  This registers the interfaces  	 * with the driver core and lets interface drivers bind to them.  	 */ -	if (usb_device_is_owned(udev)) -		;		/* Don't configure if the device is owned */ -	else if (udev->authorized == 0) +	if (udev->authorized == 0)  		dev_err(&udev->dev, "Device is not authorized for usage\n");  	else {  		c = usb_choose_configuration(udev);  		if (c >= 0) {  			err = usb_set_configuration(udev, c); -			if (err) { +			if (err && err != -ENODEV) {  				dev_err(&udev->dev, "can't set config #%d, error %d\n",  					c, err);  				/* This need not be fatal.  The user can try to diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 3799573bd38..82044b5d611 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -19,7 +19,6 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/pci.h> -#include <linux/pm_runtime.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h> @@ -38,119 +37,123 @@  /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ -#ifdef CONFIG_PM_SLEEP - -/* Coordinate handoffs between EHCI and companion controllers - * during system resume +/* + * Coordinate handoffs between EHCI and companion controllers + * during EHCI probing and system resume.   */ -static DEFINE_MUTEX(companions_mutex); +static DECLARE_RWSEM(companions_rwsem);  #define CL_UHCI		PCI_CLASS_SERIAL_USB_UHCI  #define CL_OHCI		PCI_CLASS_SERIAL_USB_OHCI  #define CL_EHCI		PCI_CLASS_SERIAL_USB_EHCI -enum companion_action { -	SET_HS_COMPANION, CLEAR_HS_COMPANION, WAIT_FOR_COMPANIONS -}; +static inline int is_ohci_or_uhci(struct pci_dev *pdev) +{ +	return pdev->class == CL_OHCI || pdev->class == CL_UHCI; +} + +typedef void (*companion_fn)(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd); -static void companion_common(struct pci_dev *pdev, struct usb_hcd *hcd, -		enum companion_action action) +/* Iterate over PCI devices in the same slot as pdev and call fn for each */ +static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd, +		companion_fn fn)  {  	struct pci_dev		*companion;  	struct usb_hcd		*companion_hcd;  	unsigned int		slot = PCI_SLOT(pdev->devfn); -	/* Iterate through other PCI functions in the same slot. -	 * If pdev is OHCI or UHCI then we are looking for EHCI, and -	 * vice versa. +	/* +	 * Iterate through other PCI functions in the same slot. +	 * If the function's drvdata isn't set then it isn't bound to +	 * a USB host controller driver, so skip it.  	 */  	companion = NULL;  	for_each_pci_dev(companion) {  		if (companion->bus != pdev->bus ||  				PCI_SLOT(companion->devfn) != slot)  			continue; -  		companion_hcd = pci_get_drvdata(companion); -		if (!companion_hcd) +		if (!companion_hcd || !companion_hcd->self.root_hub)  			continue; - -		/* For SET_HS_COMPANION, store a pointer to the EHCI bus in -		 * the OHCI/UHCI companion bus structure. -		 * For CLEAR_HS_COMPANION, clear the pointer to the EHCI bus -		 * in the OHCI/UHCI companion bus structure. -		 * For WAIT_FOR_COMPANIONS, wait until the OHCI/UHCI -		 * companion controllers have fully resumed. -		 */ - -		if ((pdev->class == CL_OHCI || pdev->class == CL_UHCI) && -				companion->class == CL_EHCI) { -			/* action must be SET_HS_COMPANION */ -			dev_dbg(&companion->dev, "HS companion for %s\n", -					dev_name(&pdev->dev)); -			hcd->self.hs_companion = &companion_hcd->self; - -		} else if (pdev->class == CL_EHCI && -				(companion->class == CL_OHCI || -				companion->class == CL_UHCI)) { -			switch (action) { -			case SET_HS_COMPANION: -				dev_dbg(&pdev->dev, "HS companion for %s\n", -						dev_name(&companion->dev)); -				companion_hcd->self.hs_companion = &hcd->self; -				break; -			case CLEAR_HS_COMPANION: -				companion_hcd->self.hs_companion = NULL; -				break; -			case WAIT_FOR_COMPANIONS: -				device_pm_wait_for_dev(&pdev->dev, -						&companion->dev); -				break; -			} -		} +		fn(pdev, hcd, companion, companion_hcd);  	}  } -static void set_hs_companion(struct pci_dev *pdev, struct usb_hcd *hcd) +/* + * We're about to add an EHCI controller, which will unceremoniously grab + * all the port connections away from its companions.  To prevent annoying + * error messages, lock the companion's root hub and gracefully unconfigure + * it beforehand.  Leave it locked until the EHCI controller is all set. + */ +static void ehci_pre_add(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd)  { -	mutex_lock(&companions_mutex); -	dev_set_drvdata(&pdev->dev, hcd); -	companion_common(pdev, hcd, SET_HS_COMPANION); -	mutex_unlock(&companions_mutex); +	struct usb_device *udev; + +	if (is_ohci_or_uhci(companion)) { +		udev = companion_hcd->self.root_hub; +		usb_lock_device(udev); +		usb_set_configuration(udev, 0); +	}  } -static void clear_hs_companion(struct pci_dev *pdev, struct usb_hcd *hcd) +/* + * Adding the EHCI controller has either succeeded or failed.  Set the + * companion pointer accordingly, and in either case, reconfigure and + * unlock the root hub. + */ +static void ehci_post_add(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd)  { -	mutex_lock(&companions_mutex); -	dev_set_drvdata(&pdev->dev, NULL); +	struct usb_device *udev; -	/* If pdev is OHCI or UHCI, just clear its hs_companion pointer */ -	if (pdev->class == CL_OHCI || pdev->class == CL_UHCI) -		hcd->self.hs_companion = NULL; +	if (is_ohci_or_uhci(companion)) { +		if (dev_get_drvdata(&pdev->dev)) {	/* Succeeded */ +			dev_dbg(&pdev->dev, "HS companion for %s\n", +					dev_name(&companion->dev)); +			companion_hcd->self.hs_companion = &hcd->self; +		} +		udev = companion_hcd->self.root_hub; +		usb_set_configuration(udev, 1); +		usb_unlock_device(udev); +	} +} -	/* Otherwise search for companion buses and clear their pointers */ -	else -		companion_common(pdev, hcd, CLEAR_HS_COMPANION); -	mutex_unlock(&companions_mutex); +/* + * We just added a non-EHCI controller.  Find the EHCI controller to + * which it is a companion, and store a pointer to the bus structure. + */ +static void non_ehci_add(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd) +{ +	if (is_ohci_or_uhci(pdev) && companion->class == CL_EHCI) { +		dev_dbg(&pdev->dev, "FS/LS companion for %s\n", +				dev_name(&companion->dev)); +		hcd->self.hs_companion = &companion_hcd->self; +	}  } -static void wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd) +/* We are removing an EHCI controller.  Clear the companions' pointers. */ +static void ehci_remove(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd)  { -	/* Only EHCI controllers need to wait. -	 * No locking is needed because a controller cannot be resumed -	 * while one of its companions is getting unbound. -	 */ -	if (pdev->class == CL_EHCI) -		companion_common(pdev, hcd, WAIT_FOR_COMPANIONS); +	if (is_ohci_or_uhci(companion)) +		companion_hcd->self.hs_companion = NULL;  } -#else /* !CONFIG_PM_SLEEP */ +#ifdef	CONFIG_PM -static inline void set_hs_companion(struct pci_dev *d, struct usb_hcd *h) {} -static inline void clear_hs_companion(struct pci_dev *d, struct usb_hcd *h) {} -static inline void wait_for_companions(struct pci_dev *d, struct usb_hcd *h) {} +/* An EHCI controller must wait for its companions before resuming. */ +static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, +		struct pci_dev *companion, struct usb_hcd *companion_hcd) +{ +	if (is_ohci_or_uhci(companion)) +		device_pm_wait_for_dev(&pdev->dev, &companion->dev); +} -#endif /* !CONFIG_PM_SLEEP */ +#endif	/* CONFIG_PM */  /*-------------------------------------------------------------------------*/ @@ -168,12 +171,15 @@ static inline void wait_for_companions(struct pci_dev *d, struct usb_hcd *h) {}   * through the hotplug entry's driver_data.   *   * Store this function in the HCD's struct pci_driver as probe(). + * + * Return: 0 if successful.   */  int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  {  	struct hc_driver	*driver;  	struct usb_hcd		*hcd;  	int			retval; +	int			hcd_irq = 0;  	if (usb_disabled())  		return -ENODEV; @@ -186,22 +192,31 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	if (pci_enable_device(dev) < 0)  		return -ENODEV; -	dev->current_state = PCI_D0; - -	if (!dev->irq) { -		dev_err(&dev->dev, -			"Found HC with no IRQ.  Check BIOS/PCI %s setup!\n", -			pci_name(dev)); -		retval = -ENODEV; -		goto err1; + +	/* +	 * The xHCI driver has its own irq management +	 * make sure irq setup is not touched for xhci in generic hcd code +	 */ +	if ((driver->flags & HCD_MASK) != HCD_USB3) { +		if (!dev->irq) { +			dev_err(&dev->dev, +			"Found HC with no IRQ. Check BIOS/PCI %s setup!\n", +				pci_name(dev)); +			retval = -ENODEV; +			goto disable_pci; +		} +		hcd_irq = dev->irq;  	}  	hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));  	if (!hcd) {  		retval = -ENOMEM; -		goto err1; +		goto disable_pci;  	} +	hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) && +			driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0; +  	if (driver->flags & HCD_MEMORY) {  		/* EHCI, OHCI */  		hcd->rsrc_start = pci_resource_start(dev, 0); @@ -210,13 +225,13 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  				driver->description)) {  			dev_dbg(&dev->dev, "controller already in use\n");  			retval = -EBUSY; -			goto err2; +			goto put_hcd;  		}  		hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);  		if (hcd->regs == NULL) {  			dev_dbg(&dev->dev, "error mapping memory\n");  			retval = -EFAULT; -			goto err3; +			goto release_mem_region;  		}  	} else { @@ -237,32 +252,51 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  		if (region == PCI_ROM_RESOURCE) {  			dev_dbg(&dev->dev, "no i/o regions available\n");  			retval = -EBUSY; -			goto err2; +			goto put_hcd;  		}  	}  	pci_set_master(dev); -	retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); +	/* Note: dev_set_drvdata must be called while holding the rwsem */ +	if (dev->class == CL_EHCI) { +		down_write(&companions_rwsem); +		dev_set_drvdata(&dev->dev, hcd); +		for_each_companion(dev, hcd, ehci_pre_add); +		retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED); +		if (retval != 0) +			dev_set_drvdata(&dev->dev, NULL); +		for_each_companion(dev, hcd, ehci_post_add); +		up_write(&companions_rwsem); +	} else { +		down_read(&companions_rwsem); +		dev_set_drvdata(&dev->dev, hcd); +		retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED); +		if (retval != 0) +			dev_set_drvdata(&dev->dev, NULL); +		else +			for_each_companion(dev, hcd, non_ehci_add); +		up_read(&companions_rwsem); +	} +  	if (retval != 0) -		goto err4; -	set_hs_companion(dev, hcd); +		goto unmap_registers; +	device_wakeup_enable(hcd->self.controller);  	if (pci_dev_run_wake(dev))  		pm_runtime_put_noidle(&dev->dev);  	return retval; - err4: +unmap_registers:  	if (driver->flags & HCD_MEMORY) {  		iounmap(hcd->regs); - err3: +release_mem_region:  		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	} else  		release_region(hcd->rsrc_start, hcd->rsrc_len); - err2: -	clear_hs_companion(dev, hcd); +put_hcd:  	usb_put_hcd(hcd); - err1: +disable_pci:  	pci_disable_device(dev);  	dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);  	return retval; @@ -303,14 +337,29 @@ void usb_hcd_pci_remove(struct pci_dev *dev)  	usb_hcd_irq(0, hcd);  	local_irq_enable(); -	usb_remove_hcd(hcd); +	/* Note: dev_set_drvdata must be called while holding the rwsem */ +	if (dev->class == CL_EHCI) { +		down_write(&companions_rwsem); +		for_each_companion(dev, hcd, ehci_remove); +		usb_remove_hcd(hcd); +		dev_set_drvdata(&dev->dev, NULL); +		up_write(&companions_rwsem); +	} else { +		/* Not EHCI; just clear the companion pointer */ +		down_read(&companions_rwsem); +		hcd->self.hs_companion = NULL; +		usb_remove_hcd(hcd); +		dev_set_drvdata(&dev->dev, NULL); +		up_read(&companions_rwsem); +	} +  	if (hcd->driver->flags & HCD_MEMORY) {  		iounmap(hcd->regs);  		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	} else {  		release_region(hcd->rsrc_start, hcd->rsrc_len);  	} -	clear_hs_companion(dev, hcd); +  	usb_put_hcd(hcd);  	pci_disable_device(dev);  } @@ -336,7 +385,7 @@ void usb_hcd_pci_shutdown(struct pci_dev *dev)  }  EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown); -#ifdef	CONFIG_PM_OPS +#ifdef	CONFIG_PM  #ifdef	CONFIG_PPC_PMAC  static void powermac_set_asic(struct pci_dev *pci_dev, int enable) @@ -364,14 +413,21 @@ static int check_root_hub_suspended(struct device *dev)  	struct pci_dev		*pci_dev = to_pci_dev(dev);  	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev); -	if (!(hcd->state == HC_STATE_SUSPENDED || -			hcd->state == HC_STATE_HALT)) { +	if (HCD_RH_RUNNING(hcd)) {  		dev_warn(dev, "Root hub is not suspended\n");  		return -EBUSY;  	} +	if (hcd->shared_hcd) { +		hcd = hcd->shared_hcd; +		if (HCD_RH_RUNNING(hcd)) { +			dev_warn(dev, "Secondary root hub is not suspended\n"); +			return -EBUSY; +		} +	}  	return 0;  } +#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)  static int suspend_common(struct device *dev, bool do_wakeup)  {  	struct pci_dev		*pci_dev = to_pci_dev(dev); @@ -387,17 +443,22 @@ static int suspend_common(struct device *dev, bool do_wakeup)  	if (retval)  		return retval; -	if (hcd->driver->pci_suspend) { +	if (hcd->driver->pci_suspend && !HCD_DEAD(hcd)) {  		/* Optimization: Don't suspend if a root-hub wakeup is  		 * pending and it would cause the HCD to wake up anyway.  		 */  		if (do_wakeup && HCD_WAKEUP_PENDING(hcd))  			return -EBUSY; +		if (do_wakeup && hcd->shared_hcd && +				HCD_WAKEUP_PENDING(hcd->shared_hcd)) +			return -EBUSY;  		retval = hcd->driver->pci_suspend(hcd, do_wakeup);  		suspend_report_result(hcd->driver->pci_suspend, retval);  		/* Check again in case wakeup raced with pci_suspend */ -		if (retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) { +		if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) || +				(retval == 0 && do_wakeup && hcd->shared_hcd && +				 HCD_WAKEUP_PENDING(hcd->shared_hcd))) {  			if (hcd->driver->pci_resume)  				hcd->driver->pci_resume(hcd, false);  			retval = -EBUSY; @@ -406,7 +467,12 @@ static int suspend_common(struct device *dev, bool do_wakeup)  			return retval;  	} -	synchronize_irq(pci_dev->irq); +	/* If MSI-X is enabled, the driver will have synchronized all vectors +	 * in pci_suspend(). If MSI or legacy PCI is enabled, that will be +	 * synchronized here. +	 */ +	if (!hcd->msix_enabled) +		synchronize_irq(pci_dev->irq);  	/* Downstream ports from this root hub should already be quiesced, so  	 * there will be no DMA activity.  Now we can shut down the upstream @@ -423,7 +489,9 @@ static int resume_common(struct device *dev, int event)  	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);  	int			retval; -	if (hcd->state != HC_STATE_SUSPENDED) { +	if (HCD_RH_RUNNING(hcd) || +			(hcd->shared_hcd && +			 HCD_RH_RUNNING(hcd->shared_hcd))) {  		dev_dbg(dev, "can't resume, not suspended!\n");  		return 0;  	} @@ -436,21 +504,29 @@ static int resume_common(struct device *dev, int event)  	pci_set_master(pci_dev); -	clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); +	if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { -	if (hcd->driver->pci_resume) { -		if (event != PM_EVENT_AUTO_RESUME) -			wait_for_companions(pci_dev, hcd); +		/* +		 * Only EHCI controllers have to wait for their companions. +		 * No locking is needed because PCI controller drivers do not +		 * get unbound during system resume. +		 */ +		if (pci_dev->class == CL_EHCI && event != PM_EVENT_AUTO_RESUME) +			for_each_companion(pci_dev, hcd, +					ehci_wait_for_companions);  		retval = hcd->driver->pci_resume(hcd,  				event == PM_EVENT_RESTORE);  		if (retval) {  			dev_err(dev, "PCI post-resume error %d!\n", retval); +			if (hcd->shared_hcd) +				usb_hc_died(hcd->shared_hcd);  			usb_hc_died(hcd);  		}  	}  	return retval;  } +#endif	/* SLEEP || RUNTIME */  #ifdef	CONFIG_PM_SLEEP @@ -471,10 +547,11 @@ static int hcd_pci_suspend_noirq(struct device *dev)  	pci_save_state(pci_dev); -	/* If the root hub is HALTed rather than SUSPENDed, -	 * disallow remote wakeup. +	/* If the root hub is dead rather than suspended, disallow remote +	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as +	 * dying, so we only need to check the primary roothub.  	 */ -	if (hcd->state == HC_STATE_HALT) +	if (HCD_DEAD(hcd))  		device_set_wakeup_enable(dev, 0);  	dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev)); @@ -576,4 +653,4 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = {  };  EXPORT_SYMBOL_GPL(usb_hcd_pci_pm_ops); -#endif	/* CONFIG_PM_OPS */ +#endif	/* CONFIG_PM */ diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 61800f77dac..bec31e2efb8 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -6,7 +6,7 @@   * (C) Copyright Deti Fliegl 1999   * (C) Copyright Randy Dunlap 2000   * (C) Copyright David Brownell 2000-2002 - *  + *   * This program is free software; you can redistribute it and/or modify it   * under the terms of the GNU General Public License as published by the   * Free Software Foundation; either version 2 of the License, or (at your @@ -22,6 +22,7 @@   * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ +#include <linux/bcd.h>  #include <linux/module.h>  #include <linux/version.h>  #include <linux/kernel.h> @@ -39,9 +40,11 @@  #include <linux/platform_device.h>  #include <linux/workqueue.h>  #include <linux/pm_runtime.h> +#include <linux/types.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h> +#include <linux/usb/phy.h>  #include "usb.h" @@ -91,10 +94,7 @@ EXPORT_SYMBOL_GPL (usb_bus_list);  /* used when allocating bus numbers */  #define USB_MAXBUS		64 -struct usb_busmap { -	unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))]; -}; -static struct usb_busmap busmap; +static DECLARE_BITMAP(busmap, USB_MAXBUS);  /* used when updating list of hcds */  DEFINE_MUTEX(usb_bus_list_lock);	/* exported only for usbfs */ @@ -124,9 +124,8 @@ static inline int is_root_hub(struct usb_device *udev)   */  /*-------------------------------------------------------------------------*/ - -#define KERNEL_REL	((LINUX_VERSION_CODE >> 16) & 0x0ff) -#define KERNEL_VER	((LINUX_VERSION_CODE >> 8) & 0x0ff) +#define KERNEL_REL	bin2bcd(((LINUX_VERSION_CODE >> 16) & 0x0ff)) +#define KERNEL_VER	bin2bcd(((LINUX_VERSION_CODE >> 8) & 0x0ff))  /* usb 3.0 root hub device descriptor */  static const u8 usb3_rh_dev_descriptor[18] = { @@ -139,7 +138,7 @@ static const u8 usb3_rh_dev_descriptor[18] = {  	0x03,       /*  __u8  bDeviceProtocol; USB 3.0 hub */  	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */ -	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */ +	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */  	0x03, 0x00, /*  __le16 idProduct; device 0x0003 */  	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */ @@ -149,8 +148,29 @@ static const u8 usb3_rh_dev_descriptor[18] = {  	0x01        /*  __u8  bNumConfigurations; */  }; +/* usb 2.5 (wireless USB 1.0) root hub device descriptor */ +static const u8 usb25_rh_dev_descriptor[18] = { +	0x12,       /*  __u8  bLength; */ +	0x01,       /*  __u8  bDescriptorType; Device */ +	0x50, 0x02, /*  __le16 bcdUSB; v2.5 */ + +	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */ +	0x00,	    /*  __u8  bDeviceSubClass; */ +	0x00,       /*  __u8  bDeviceProtocol; [ usb 2.0 no TT ] */ +	0xFF,       /*  __u8  bMaxPacketSize0; always 0xFF (WUSB Spec 7.4.1). */ + +	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */ +	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */ +	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */ + +	0x03,       /*  __u8  iManufacturer; */ +	0x02,       /*  __u8  iProduct; */ +	0x01,       /*  __u8  iSerialNumber; */ +	0x01        /*  __u8  bNumConfigurations; */ +}; +  /* usb 2.0 root hub device descriptor */ -static const u8 usb2_rh_dev_descriptor [18] = { +static const u8 usb2_rh_dev_descriptor[18] = {  	0x12,       /*  __u8  bLength; */  	0x01,       /*  __u8  bDescriptorType; Device */  	0x00, 0x02, /*  __le16 bcdUSB; v2.0 */ @@ -160,7 +180,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {  	0x00,       /*  __u8  bDeviceProtocol; [ usb 2.0 no TT ] */  	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */ -	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */ +	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */  	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */  	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */ @@ -173,7 +193,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {  /* no usb 2.0 root hub "device qualifier" descriptor: one speed only */  /* usb 1.1 root hub device descriptor */ -static const u8 usb11_rh_dev_descriptor [18] = { +static const u8 usb11_rh_dev_descriptor[18] = {  	0x12,       /*  __u8  bLength; */  	0x01,       /*  __u8  bDescriptorType; Device */  	0x10, 0x01, /*  __le16 bcdUSB; v1.1 */ @@ -183,7 +203,7 @@ static const u8 usb11_rh_dev_descriptor [18] = {  	0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */  	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */ -	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */ +	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */  	0x01, 0x00, /*  __le16 idProduct; device 0x0001 */  	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */ @@ -198,7 +218,7 @@ static const u8 usb11_rh_dev_descriptor [18] = {  /* Configuration descriptors for our root hubs */ -static const u8 fs_rh_config_descriptor [] = { +static const u8 fs_rh_config_descriptor[] = {  	/* one configuration */  	0x09,       /*  __u8  bLength; */ @@ -207,13 +227,13 @@ static const u8 fs_rh_config_descriptor [] = {  	0x01,       /*  __u8  bNumInterfaces; (1) */  	0x01,       /*  __u8  bConfigurationValue; */  	0x00,       /*  __u8  iConfiguration; */ -	0xc0,       /*  __u8  bmAttributes;  +	0xc0,       /*  __u8  bmAttributes;  				 Bit 7: must be set,  				     6: Self-powered,  				     5: Remote wakeup,  				     4..0: resvd */  	0x00,       /*  __u8  MaxPower; */ -       +  	/* USB 1.1:  	 * USB 2.0, single TT organization (mandatory):  	 *	one interface, protocol 0 @@ -235,17 +255,17 @@ static const u8 fs_rh_config_descriptor [] = {  	0x00,       /*  __u8  if_bInterfaceSubClass; */  	0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */  	0x00,       /*  __u8  if_iInterface; */ -      +  	/* one endpoint (status change endpoint) */  	0x07,       /*  __u8  ep_bLength; */  	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */  	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */ - 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */ - 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ +	0x03,       /*  __u8  ep_bmAttributes; Interrupt */ +	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */  	0xff        /*  __u8  ep_bInterval; (255ms -- usb 2.0 spec) */  }; -static const u8 hs_rh_config_descriptor [] = { +static const u8 hs_rh_config_descriptor[] = {  	/* one configuration */  	0x09,       /*  __u8  bLength; */ @@ -254,13 +274,13 @@ static const u8 hs_rh_config_descriptor [] = {  	0x01,       /*  __u8  bNumInterfaces; (1) */  	0x01,       /*  __u8  bConfigurationValue; */  	0x00,       /*  __u8  iConfiguration; */ -	0xc0,       /*  __u8  bmAttributes;  +	0xc0,       /*  __u8  bmAttributes;  				 Bit 7: must be set,  				     6: Self-powered,  				     5: Remote wakeup,  				     4..0: resvd */  	0x00,       /*  __u8  MaxPower; */ -       +  	/* USB 1.1:  	 * USB 2.0, single TT organization (mandatory):  	 *	one interface, protocol 0 @@ -282,12 +302,12 @@ static const u8 hs_rh_config_descriptor [] = {  	0x00,       /*  __u8  if_bInterfaceSubClass; */  	0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */  	0x00,       /*  __u8  if_iInterface; */ -      +  	/* one endpoint (status change endpoint) */  	0x07,       /*  __u8  ep_bLength; */  	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */  	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */ - 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */ +	0x03,       /*  __u8  ep_bmAttributes; Interrupt */  		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)  		     * see hub.c:hub_configure() for details. */  	(USB_MAXCHILDREN + 1 + 7) / 8, 0x00, @@ -298,7 +318,7 @@ static const u8 ss_rh_config_descriptor[] = {  	/* one configuration */  	0x09,       /*  __u8  bLength; */  	0x02,       /*  __u8  bDescriptorType; Configuration */ -	0x19, 0x00, /*  __le16 wTotalLength; FIXME */ +	0x1f, 0x00, /*  __le16 wTotalLength; */  	0x01,       /*  __u8  bNumInterfaces; (1) */  	0x01,       /*  __u8  bConfigurationValue; */  	0x00,       /*  __u8  iConfiguration; */ @@ -328,13 +348,27 @@ static const u8 ss_rh_config_descriptor[] = {  		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)  		     * see hub.c:hub_configure() for details. */  	(USB_MAXCHILDREN + 1 + 7) / 8, 0x00, -	0x0c        /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */ -	/* -	 * All 3.0 hubs should have an endpoint companion descriptor, -	 * but we're ignoring that for now.  FIXME? -	 */ +	0x0c,       /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */ + +	/* one SuperSpeed endpoint companion descriptor */ +	0x06,        /* __u8 ss_bLength */ +	0x30,        /* __u8 ss_bDescriptorType; SuperSpeed EP Companion */ +	0x00,        /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */ +	0x00,        /* __u8 ss_bmAttributes; 1 packet per service interval */ +	0x02, 0x00   /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */  }; +/* authorized_default behaviour: + * -1 is authorized for all devices except wireless (old behaviour) + * 0 is unauthorized for all devices + * 1 is authorized for all devices + */ +static int authorized_default = -1; +module_param(authorized_default, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(authorized_default, +		"Default USB device authorization: 0 is not authorized, 1 is " +		"authorized, -1 is authorized except for wireless USB (default, " +		"old behaviour");  /*-------------------------------------------------------------------------*/  /** @@ -343,9 +377,10 @@ static const u8 ss_rh_config_descriptor[] = {   * @buf: Buffer for USB string descriptor (header + UTF-16LE)   * @len: Length (in bytes; may be odd) of descriptor buffer.   * - * The return value is the number of bytes filled in: 2 + 2*strlen(s) or - * buflen, whichever is less. + * Return: The number of bytes filled in: 2 + 2*strlen(s) or @len, + * whichever is less.   * + * Note:   * USB String descriptors can contain at most 126 characters; input   * strings longer than that are truncated.   */ @@ -381,7 +416,8 @@ ascii2desc(char const *s, u8 *buf, unsigned len)   *   * Produces either a manufacturer, product or serial number string for the   * virtual root hub device. - * Returns the number of bytes filled in: the length of the descriptor or + * + * Return: The number of bytes filled in: the length of the descriptor or   * of the provided buffer, whichever is less.   */  static unsigned @@ -391,7 +427,7 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len)  	char const *s;  	static char const langids[4] = {4, USB_DT_STRING, 0x09, 0x04}; -	// language ids +	/* language ids */  	switch (id) {  	case 0:  		/* Array of LANGID codes (0x0409 is MSFT-speak for "en-us") */ @@ -427,15 +463,15 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len)  static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  {  	struct usb_ctrlrequest *cmd; - 	u16		typeReq, wValue, wIndex, wLength; +	u16		typeReq, wValue, wIndex, wLength;  	u8		*ubuf = urb->transfer_buffer; -	u8		tbuf [sizeof (struct usb_hub_descriptor)] -		__attribute__((aligned(4))); -	const u8	*bufp = tbuf;  	unsigned	len = 0;  	int		status;  	u8		patch_wakeup = 0;  	u8		patch_protocol = 0; +	u16		tbuf_size; +	u8		*tbuf = NULL; +	const u8	*bufp;  	might_sleep(); @@ -455,6 +491,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  	if (wLength > urb->transfer_buffer_length)  		goto error; +	/* +	 * tbuf should be at least as big as the +	 * USB hub descriptor. +	 */ +	tbuf_size =  max_t(u16, sizeof(struct usb_hub_descriptor), wLength); +	tbuf = kzalloc(tbuf_size, GFP_KERNEL); +	if (!tbuf) +		return -ENOMEM; + +	bufp = tbuf; + +  	urb->actual_length = 0;  	switch (typeReq) { @@ -477,10 +525,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  	 */  	case DeviceRequest | USB_REQ_GET_STATUS: -		tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev) +		tbuf[0] = (device_may_wakeup(&hcd->self.root_hub->dev)  					<< USB_DEVICE_REMOTE_WAKEUP)  				| (1 << USB_DEVICE_SELF_POWERED); -		tbuf [1] = 0; +		tbuf[1] = 0;  		len = 2;  		break;  	case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: @@ -497,7 +545,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  			goto error;  		break;  	case DeviceRequest | USB_REQ_GET_CONFIGURATION: -		tbuf [0] = 1; +		tbuf[0] = 1;  		len = 1;  			/* FALLTHROUGH */  	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: @@ -505,10 +553,13 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:  		switch (wValue & 0xff00) {  		case USB_DT_DEVICE << 8: -			switch (hcd->driver->flags & HCD_MASK) { +			switch (hcd->speed) {  			case HCD_USB3:  				bufp = usb3_rh_dev_descriptor;  				break; +			case HCD_USB25: +				bufp = usb25_rh_dev_descriptor; +				break;  			case HCD_USB2:  				bufp = usb2_rh_dev_descriptor;  				break; @@ -523,11 +574,12 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  				patch_protocol = 1;  			break;  		case USB_DT_CONFIG << 8: -			switch (hcd->driver->flags & HCD_MASK) { +			switch (hcd->speed) {  			case HCD_USB3:  				bufp = ss_rh_config_descriptor;  				len = sizeof ss_rh_config_descriptor;  				break; +			case HCD_USB25:  			case HCD_USB2:  				bufp = hs_rh_config_descriptor;  				len = sizeof hs_rh_config_descriptor; @@ -549,18 +601,20 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  			else /* unsupported IDs --> "protocol stall" */  				goto error;  			break; +		case USB_DT_BOS << 8: +			goto nongeneric;  		default:  			goto error;  		}  		break;  	case DeviceRequest | USB_REQ_GET_INTERFACE: -		tbuf [0] = 0; +		tbuf[0] = 0;  		len = 1;  			/* FALLTHROUGH */  	case DeviceOutRequest | USB_REQ_SET_INTERFACE:  		break;  	case DeviceOutRequest | USB_REQ_SET_ADDRESS: -		// wValue == urb->dev->devaddr +		/* wValue == urb->dev->devaddr */  		dev_dbg (hcd->self.controller, "root hub device address %d\n",  			wValue);  		break; @@ -570,9 +624,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  	/* ENDPOINT REQUESTS */  	case EndpointRequest | USB_REQ_GET_STATUS: -		// ENDPOINT_HALT flag -		tbuf [0] = 0; -		tbuf [1] = 0; +		/* ENDPOINT_HALT flag */ +		tbuf[0] = 0; +		tbuf[1] = 0;  		len = 2;  			/* FALLTHROUGH */  	case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: @@ -583,6 +637,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  	/* CLASS REQUESTS (and errors) */  	default: +nongeneric:  		/* non-generic request */  		switch (typeReq) {  		case GetHubStatus: @@ -592,17 +647,24 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)  		case GetHubDescriptor:  			len = sizeof (struct usb_hub_descriptor);  			break; +		case DeviceRequest | USB_REQ_GET_DESCRIPTOR: +			/* len is returned by hub_control */ +			break;  		}  		status = hcd->driver->hub_control (hcd,  			typeReq, wValue, wIndex,  			tbuf, wLength); + +		if (typeReq == GetHubDescriptor) +			usb_hub_adjust_deviceremovable(hcd->self.root_hub, +				(struct usb_hub_descriptor *)tbuf);  		break;  error:  		/* "protocol stall" on error */  		status = -EPIPE;  	} -	if (status) { +	if (status < 0) {  		len = 0;  		if (status != -EPIPE) {  			dev_dbg (hcd->self.controller, @@ -611,12 +673,16 @@ error:  				typeReq, wValue, wIndex,  				wLength, status);  		} +	} else if (status > 0) { +		/* hub_control may return the length of data copied. */ +		len = status; +		status = 0;  	}  	if (len) {  		if (urb->transfer_buffer_length < len)  			len = urb->transfer_buffer_length;  		urb->actual_length = len; -		// always USB_DIR_IN, toward host +		/* always USB_DIR_IN, toward host */  		memcpy (ubuf, bufp, len);  		/* report whether RH hardware supports remote wakeup */ @@ -631,21 +697,15 @@ error:  				len > offsetof(struct usb_device_descriptor,  						bDeviceProtocol))  			((struct usb_device_descriptor *) ubuf)-> -					bDeviceProtocol = 1; +				bDeviceProtocol = USB_HUB_PR_HS_SINGLE_TT;  	} +	kfree(tbuf); +  	/* any errors get returned through the urb completion */  	spin_lock_irq(&hcd_root_hub_lock);  	usb_hcd_unlink_urb_from_ep(hcd, urb); - -	/* This peculiar use of spinlocks echoes what real HC drivers do. -	 * Avoiding calls to local_irq_disable/enable makes the code -	 * RT-friendly. -	 */ -	spin_unlock(&hcd_root_hub_lock);  	usb_hcd_giveback_urb(hcd, urb, status); -	spin_lock(&hcd_root_hub_lock); -  	spin_unlock_irq(&hcd_root_hub_lock);  	return 0;  } @@ -685,9 +745,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)  			memcpy(urb->transfer_buffer, buffer, length);  			usb_hcd_unlink_urb_from_ep(hcd, urb); -			spin_unlock(&hcd_root_hub_lock);  			usb_hcd_giveback_urb(hcd, urb, 0); -			spin_lock(&hcd_root_hub_lock);  		} else {  			length = 0;  			set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags); @@ -698,7 +756,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)  	/* The USB 2.0 spec says 256 ms.  This is close enough and won't  	 * exceed that limit if HZ is 100. The math is more clunky than  	 * maybe expected, this is to make sure that all timers for USB devices -	 * fire at the same time to give the CPU a break inbetween */ +	 * fire at the same time to give the CPU a break in between */  	if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) :  			(length == 0 && hcd->status_urb != NULL))  		mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); @@ -777,10 +835,7 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  		if (urb == hcd->status_urb) {  			hcd->status_urb = NULL;  			usb_hcd_unlink_urb_from_ep(hcd, urb); - -			spin_unlock(&hcd_root_hub_lock);  			usb_hcd_giveback_urb(hcd, urb, status); -			spin_lock(&hcd_root_hub_lock);  		}  	}   done: @@ -793,9 +848,8 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  /*   * Show & store the current value of authorized_default   */ -static ssize_t usb_host_authorized_default_show(struct device *dev, -						struct device_attribute *attr, -						char *buf) +static ssize_t authorized_default_show(struct device *dev, +				       struct device_attribute *attr, char *buf)  {  	struct usb_device *rh_usb_dev = to_usb_device(dev);  	struct usb_bus *usb_bus = rh_usb_dev->bus; @@ -807,9 +861,9 @@ static ssize_t usb_host_authorized_default_show(struct device *dev,  	return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default);  } -static ssize_t usb_host_authorized_default_store(struct device *dev, -						 struct device_attribute *attr, -						 const char *buf, size_t size) +static ssize_t authorized_default_store(struct device *dev, +					struct device_attribute *attr, +					const char *buf, size_t size)  {  	ssize_t result;  	unsigned val; @@ -822,18 +876,14 @@ static ssize_t usb_host_authorized_default_store(struct device *dev,  	usb_hcd = bus_to_hcd(usb_bus);  	result = sscanf(buf, "%u\n", &val);  	if (result == 1) { -		usb_hcd->authorized_default = val? 1 : 0; +		usb_hcd->authorized_default = val ? 1 : 0;  		result = size; -	} -	else +	} else {  		result = -EINVAL; +	}  	return result;  } - -static DEVICE_ATTR(authorized_default, 0644, -	    usb_host_authorized_default_show, -	    usb_host_authorized_default_store); - +static DEVICE_ATTR_RW(authorized_default);  /* Group all the USB bus attributes */  static struct attribute *usb_bus_attrs[] = { @@ -868,6 +918,7 @@ static void usb_bus_init (struct usb_bus *bus)  	bus->bandwidth_allocated = 0;  	bus->bandwidth_int_reqs  = 0;  	bus->bandwidth_isoc_reqs = 0; +	mutex_init(&bus->usb_address0_mutex);  	INIT_LIST_HEAD (&bus->bus_list);  } @@ -881,6 +932,8 @@ static void usb_bus_init (struct usb_bus *bus)   *   * Assigns a bus number, and links the controller into usbcore data   * structures so that it can be seen by scanning the bus list. + * + * Return: 0 if successful. A negative error code otherwise.   */  static int usb_register_bus(struct usb_bus *bus)  { @@ -888,12 +941,12 @@ static int usb_register_bus(struct usb_bus *bus)  	int busnum;  	mutex_lock(&usb_bus_list_lock); -	busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); +	busnum = find_next_zero_bit(busmap, USB_MAXBUS, 1);  	if (busnum >= USB_MAXBUS) {  		printk (KERN_ERR "%s: too many buses\n", usbcore_name);  		goto error_find_busnum;  	} -	set_bit (busnum, busmap.busmap); +	set_bit(busnum, busmap);  	bus->busnum = busnum;  	/* Add it to the local list of buses */ @@ -934,7 +987,7 @@ static void usb_deregister_bus (struct usb_bus *bus)  	usb_notify_remove_bus(bus); -	clear_bit (bus->busnum, busmap.busmap); +	clear_bit(bus->busnum, busmap);  }  /** @@ -945,6 +998,8 @@ static void usb_deregister_bus (struct usb_bus *bus)   * the device properly in the device tree and then calls usb_new_device()   * to register the usb device.  It also assigns the root hub's USB address   * (always 1). + * + * Return: 0 if successful. A negative error code otherwise.   */  static int register_root_hub(struct usb_hcd *hcd)  { @@ -970,27 +1025,77 @@ static int register_root_hub(struct usb_hcd *hcd)  				dev_name(&usb_dev->dev), retval);  		return (retval < 0) ? retval : -EMSGSIZE;  	} +	if (usb_dev->speed == USB_SPEED_SUPER) { +		retval = usb_get_bos_descriptor(usb_dev); +		if (retval < 0) { +			mutex_unlock(&usb_bus_list_lock); +			dev_dbg(parent_dev, "can't read %s bos descriptor %d\n", +					dev_name(&usb_dev->dev), retval); +			return retval; +		} +	}  	retval = usb_new_device (usb_dev);  	if (retval) {  		dev_err (parent_dev, "can't register root hub for %s, %d\n",  				dev_name(&usb_dev->dev), retval); -	} -	mutex_unlock(&usb_bus_list_lock); - -	if (retval == 0) { +	} else {  		spin_lock_irq (&hcd_root_hub_lock);  		hcd->rh_registered = 1;  		spin_unlock_irq (&hcd_root_hub_lock);  		/* Did the HC die before the root hub was registered? */ -		if (hcd->state == HC_STATE_HALT) +		if (HCD_DEAD(hcd))  			usb_hc_died (hcd);	/* This time clean up */  	} +	mutex_unlock(&usb_bus_list_lock);  	return retval;  } +/* + * usb_hcd_start_port_resume - a root-hub port is sending a resume signal + * @bus: the bus which the root hub belongs to + * @portnum: the port which is being resumed + * + * HCDs should call this function when they know that a resume signal is + * being sent to a root-hub port.  The root hub will be prevented from + * going into autosuspend until usb_hcd_end_port_resume() is called. + * + * The bus's private lock must be held by the caller. + */ +void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum) +{ +	unsigned bit = 1 << portnum; + +	if (!(bus->resuming_ports & bit)) { +		bus->resuming_ports |= bit; +		pm_runtime_get_noresume(&bus->root_hub->dev); +	} +} +EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume); + +/* + * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal + * @bus: the bus which the root hub belongs to + * @portnum: the port which is being resumed + * + * HCDs should call this function when they know that a resume signal has + * stopped being sent to a root-hub port.  The root hub will be allowed to + * autosuspend again. + * + * The bus's private lock must be held by the caller. + */ +void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum) +{ +	unsigned bit = 1 << portnum; + +	if (bus->resuming_ports & bit) { +		bus->resuming_ports &= ~bit; +		pm_runtime_put_noidle(&bus->root_hub->dev); +	} +} +EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);  /*-------------------------------------------------------------------------*/ @@ -1001,7 +1106,9 @@ static int register_root_hub(struct usb_hcd *hcd)   * @isoc: true for isochronous transactions, false for interrupt ones   * @bytecount: how many bytes in the transaction.   * - * Returns approximate bus time in nanoseconds for a periodic transaction. + * Return: Approximate bus time in nanoseconds for a periodic transaction. + * + * Note:   * See USB 2.0 spec section 5.11.3; only periodic transfers need to be   * scheduled in software, this function is only used for such scheduling.   */ @@ -1013,21 +1120,21 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)  	case USB_SPEED_LOW: 	/* INTR only */  		if (is_input) {  			tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L; -			return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); +			return 64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp;  		} else {  			tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L; -			return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); +			return 64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp;  		}  	case USB_SPEED_FULL:	/* ISOC or INTR */  		if (isoc) {  			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; -			return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp); +			return ((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp;  		} else {  			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; -			return (9107L + BW_HOST_DELAY + tmp); +			return 9107L + BW_HOST_DELAY + tmp;  		}  	case USB_SPEED_HIGH:	/* ISOC or INTR */ -		// FIXME adjust for input vs output +		/* FIXME adjust for input vs output */  		if (isoc)  			tmp = HS_NSECS_ISO (bytecount);  		else @@ -1059,7 +1166,7 @@ EXPORT_SYMBOL_GPL(usb_calc_bus_time);   * be disabled.  The actions carried out here are required for URB   * submission, as well as for endpoint shutdown and for usb_kill_urb.   * - * Returns 0 for no error, otherwise a negative error code (in which case + * Return: 0 for no error, otherwise a negative error code (in which case   * the enqueue() method must fail).  If no error occurs but enqueue() fails   * anyway, it must call usb_hcd_unlink_urb_from_ep() before releasing   * the private spinlock and returning. @@ -1090,13 +1197,10 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)  	 * Check the host controller's state and add the URB to the  	 * endpoint's queue.  	 */ -	switch (hcd->state) { -	case HC_STATE_RUNNING: -	case HC_STATE_RESUMING: +	if (HCD_RH_RUNNING(hcd)) {  		urb->unlinked = 0;  		list_add_tail(&urb->urb_list, &urb->ep->urb_list); -		break; -	default: +	} else {  		rc = -ESHUTDOWN;  		goto done;  	} @@ -1117,7 +1221,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_link_urb_to_ep);   * be disabled.  The actions carried out here are required for making   * sure than an unlink is valid.   * - * Returns 0 for no error, otherwise a negative error code (in which case + * Return: 0 for no error, otherwise a negative error code (in which case   * the dequeue() method must fail).  The possible error codes are:   *   *	-EIDRM: @urb was not submitted or has already completed. @@ -1144,18 +1248,6 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,  	if (urb->unlinked)  		return -EBUSY;  	urb->unlinked = status; - -	/* IRQ setup can easily be broken so that USB controllers -	 * never get completion IRQs ... maybe even the ones we need to -	 * finish unlinking the initial failed usb_set_address() -	 * or device descriptor fetch. -	 */ -	if (!HCD_SAW_IRQ(hcd) && !is_root_hub(urb->dev)) { -		dev_warn(hcd->self.controller, "Unlink after no-IRQ?  " -			"Controller is probably using the wrong IRQ.\n"); -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); -	} -  	return 0;  }  EXPORT_SYMBOL_GPL(usb_hcd_check_unlink_urb); @@ -1206,7 +1298,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep);   *   DMA framework is dma_declare_coherent_memory()   *   * - So we use that, even though the primary requirement - *   is that the memory be "local" (hence addressible + *   is that the memory be "local" (hence addressable   *   by that device), not "coherent".   *   */ @@ -1263,7 +1355,7 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,  	*dma_handle = 0;  } -void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) +void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb)  {  	if (urb->transfer_flags & URB_SETUP_MAP_SINGLE)  		dma_unmap_single(hcd->self.controller, @@ -1280,13 +1372,21 @@ void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb)  	/* Make it safe to call this routine more than once */  	urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL);  } -EXPORT_SYMBOL_GPL(unmap_urb_setup_for_dma); +EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_setup_for_dma); -void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ +	if (hcd->driver->unmap_urb_for_dma) +		hcd->driver->unmap_urb_for_dma(hcd, urb); +	else +		usb_hcd_unmap_urb_for_dma(hcd, urb); +} + +void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)  {  	enum dma_data_direction dir; -	unmap_urb_setup_for_dma(hcd, urb); +	usb_hcd_unmap_urb_setup_for_dma(hcd, urb);  	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;  	if (urb->transfer_flags & URB_DMA_MAP_SG) @@ -1315,11 +1415,20 @@ void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)  	urb->transfer_flags &= ~(URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |  			URB_DMA_MAP_SINGLE | URB_MAP_LOCAL);  } -EXPORT_SYMBOL_GPL(unmap_urb_for_dma); +EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_for_dma);  static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  			   gfp_t mem_flags)  { +	if (hcd->driver->map_urb_for_dma) +		return hcd->driver->map_urb_for_dma(hcd, urb, mem_flags); +	else +		return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); +} + +int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, +			    gfp_t mem_flags) +{  	enum dma_data_direction dir;  	int ret = 0; @@ -1330,6 +1439,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  	 */  	if (usb_endpoint_xfer_control(&urb->ep->desc)) { +		if (hcd->self.uses_pio_for_control) +			return ret;  		if (hcd->self.uses_dma) {  			urb->setup_dma = dma_map_single(  					hcd->self.controller, @@ -1358,7 +1469,15 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  	    && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {  		if (hcd->self.uses_dma) {  			if (urb->num_sgs) { -				int n = dma_map_sg( +				int n; + +				/* We don't support sg for isoc transfers ! */ +				if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { +					WARN_ON(1); +					return -EINVAL; +				} + +				n = dma_map_sg(  						hcd->self.controller,  						urb->sg,  						urb->num_sgs, @@ -1367,11 +1486,10 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  					ret = -EAGAIN;  				else  					urb->transfer_flags |= URB_DMA_MAP_SG; -				if (n != urb->num_sgs) { -					urb->num_sgs = n; +				urb->num_mapped_sgs = n; +				if (n != urb->num_sgs)  					urb->transfer_flags |=  							URB_DMA_SG_COMBINED; -				}  			} else if (urb->sg) {  				struct scatterlist *sg = urb->sg;  				urb->transfer_dma = dma_map_page( @@ -1385,6 +1503,9 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  					ret = -EAGAIN;  				else  					urb->transfer_flags |= URB_DMA_MAP_PAGE; +			} else if (is_vmalloc_addr(urb->transfer_buffer)) { +				WARN_ONCE(1, "transfer buffer not dma capable\n"); +				ret = -EAGAIN;  			} else {  				urb->transfer_dma = dma_map_single(  						hcd->self.controller, @@ -1409,10 +1530,11 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  		}  		if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE |  				URB_SETUP_MAP_LOCAL))) -			unmap_urb_for_dma(hcd, urb); +			usb_hcd_unmap_urb_for_dma(hcd, urb);  	}  	return ret;  } +EXPORT_SYMBOL_GPL(usb_hcd_map_urb_for_dma);  /*-------------------------------------------------------------------------*/ @@ -1529,6 +1651,77 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)  /*-------------------------------------------------------------------------*/ +static void __usb_hcd_giveback_urb(struct urb *urb) +{ +	struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); +	struct usb_anchor *anchor = urb->anchor; +	int status = urb->unlinked; +	unsigned long flags; + +	urb->hcpriv = NULL; +	if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && +	    urb->actual_length < urb->transfer_buffer_length && +	    !status)) +		status = -EREMOTEIO; + +	unmap_urb_for_dma(hcd, urb); +	usbmon_urb_complete(&hcd->self, urb, status); +	usb_anchor_suspend_wakeups(anchor); +	usb_unanchor_urb(urb); + +	/* pass ownership to the completion handler */ +	urb->status = status; + +	/* +	 * We disable local IRQs here avoid possible deadlock because +	 * drivers may call spin_lock() to hold lock which might be +	 * acquired in one hard interrupt handler. +	 * +	 * The local_irq_save()/local_irq_restore() around complete() +	 * will be removed if current USB drivers have been cleaned up +	 * and no one may trigger the above deadlock situation when +	 * running complete() in tasklet. +	 */ +	local_irq_save(flags); +	urb->complete(urb); +	local_irq_restore(flags); + +	usb_anchor_resume_wakeups(anchor); +	atomic_dec(&urb->use_count); +	if (unlikely(atomic_read(&urb->reject))) +		wake_up(&usb_kill_urb_queue); +	usb_put_urb(urb); +} + +static void usb_giveback_urb_bh(unsigned long param) +{ +	struct giveback_urb_bh *bh = (struct giveback_urb_bh *)param; +	struct list_head local_list; + +	spin_lock_irq(&bh->lock); +	bh->running = true; + restart: +	list_replace_init(&bh->head, &local_list); +	spin_unlock_irq(&bh->lock); + +	while (!list_empty(&local_list)) { +		struct urb *urb; + +		urb = list_entry(local_list.next, struct urb, urb_list); +		list_del_init(&urb->urb_list); +		bh->completing_ep = urb->ep; +		__usb_hcd_giveback_urb(urb); +		bh->completing_ep = NULL; +	} + +	/* check if there are new URBs to giveback */ +	spin_lock_irq(&bh->lock); +	if (!list_empty(&bh->head)) +		goto restart; +	bh->running = false; +	spin_unlock_irq(&bh->lock); +} +  /**   * usb_hcd_giveback_urb - return URB from HCD to device driver   * @hcd: host controller returning the URB @@ -1548,25 +1741,37 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)   */  void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)  { -	urb->hcpriv = NULL; -	if (unlikely(urb->unlinked)) -		status = urb->unlinked; -	else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && -			urb->actual_length < urb->transfer_buffer_length && -			!status)) -		status = -EREMOTEIO; +	struct giveback_urb_bh *bh; +	bool running, high_prio_bh; -	unmap_urb_for_dma(hcd, urb); -	usbmon_urb_complete(&hcd->self, urb, status); -	usb_unanchor_urb(urb); +	/* pass status to tasklet via unlinked */ +	if (likely(!urb->unlinked)) +		urb->unlinked = status; -	/* pass ownership to the completion handler */ -	urb->status = status; -	urb->complete (urb); -	atomic_dec (&urb->use_count); -	if (unlikely(atomic_read(&urb->reject))) -		wake_up (&usb_kill_urb_queue); -	usb_put_urb (urb); +	if (!hcd_giveback_urb_in_bh(hcd) && !is_root_hub(urb->dev)) { +		__usb_hcd_giveback_urb(urb); +		return; +	} + +	if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) { +		bh = &hcd->high_prio_bh; +		high_prio_bh = true; +	} else { +		bh = &hcd->low_prio_bh; +		high_prio_bh = false; +	} + +	spin_lock(&bh->lock); +	list_add_tail(&urb->urb_list, &bh->head); +	running = bh->running; +	spin_unlock(&bh->lock); + +	if (running) +		; +	else if (high_prio_bh) +		tasklet_hi_schedule(&bh->bh); +	else +		tasklet_schedule(&bh->bh);  }  EXPORT_SYMBOL_GPL(usb_hcd_giveback_urb); @@ -1615,7 +1820,7 @@ rescan:  				 case USB_ENDPOINT_XFER_INT:  					s = "-intr"; break;  				 default: -			 		s = "-iso"; break; +					s = "-iso"; break;  				};  				s;  			})); @@ -1665,7 +1870,7 @@ rescan:   * pass in the current alternate interface setting in cur_alt,   * and pass in the new alternate interface setting in new_alt.   * - * Returns an error if the requested bandwidth change exceeds the + * Return: An error if the requested bandwidth change exceeds the   * bus bandwidth or host controller internal resources.   */  int usb_hcd_alloc_bandwidth(struct usb_device *udev, @@ -1743,6 +1948,8 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,  		struct usb_interface *iface = usb_ifnum_to_if(udev,  				cur_alt->desc.bInterfaceNumber); +		if (!iface) +			return -EINVAL;  		if (iface->resetting_device) {  			/*  			 * The USB core just reset the device, so the xHCI host @@ -1833,9 +2040,12 @@ void usb_hcd_reset_endpoint(struct usb_device *udev,   * @num_streams:	number of streams to allocate.   * @mem_flags:		flags hcd should use to allocate memory.   * - * Sets up a group of bulk endpoints to have num_streams stream IDs available. + * Sets up a group of bulk endpoints to have @num_streams stream IDs available.   * Drivers may queue multiple transfers to different stream IDs, which may   * complete in a different order than they were queued. + * + * Return: On success, the number of allocated streams. On failure, a negative + * error code.   */  int usb_alloc_streams(struct usb_interface *interface,  		struct usb_host_endpoint **eps, unsigned int num_eps, @@ -1843,7 +2053,7 @@ int usb_alloc_streams(struct usb_interface *interface,  {  	struct usb_hcd *hcd;  	struct usb_device *dev; -	int i; +	int i, ret;  	dev = interface_to_usbdev(interface);  	hcd = bus_to_hcd(dev->bus); @@ -1852,13 +2062,24 @@ int usb_alloc_streams(struct usb_interface *interface,  	if (dev->speed != USB_SPEED_SUPER)  		return -EINVAL; -	/* Streams only apply to bulk endpoints. */ -	for (i = 0; i < num_eps; i++) +	for (i = 0; i < num_eps; i++) { +		/* Streams only apply to bulk endpoints. */  		if (!usb_endpoint_xfer_bulk(&eps[i]->desc))  			return -EINVAL; +		/* Re-alloc is not allowed */ +		if (eps[i]->streams) +			return -EINVAL; +	} -	return hcd->driver->alloc_streams(hcd, dev, eps, num_eps, +	ret = hcd->driver->alloc_streams(hcd, dev, eps, num_eps,  			num_streams, mem_flags); +	if (ret < 0) +		return ret; + +	for (i = 0; i < num_eps; i++) +		eps[i]->streams = ret; + +	return ret;  }  EXPORT_SYMBOL_GPL(usb_alloc_streams); @@ -1871,26 +2092,35 @@ EXPORT_SYMBOL_GPL(usb_alloc_streams);   *   * Reverts a group of bulk endpoints back to not using stream IDs.   * Can fail if we are given bad arguments, or HCD is broken. + * + * Return: 0 on success. On failure, a negative error code.   */ -void usb_free_streams(struct usb_interface *interface, +int usb_free_streams(struct usb_interface *interface,  		struct usb_host_endpoint **eps, unsigned int num_eps,  		gfp_t mem_flags)  {  	struct usb_hcd *hcd;  	struct usb_device *dev; -	int i; +	int i, ret;  	dev = interface_to_usbdev(interface);  	hcd = bus_to_hcd(dev->bus);  	if (dev->speed != USB_SPEED_SUPER) -		return; +		return -EINVAL; -	/* Streams only apply to bulk endpoints. */ +	/* Double-free is not allowed */  	for (i = 0; i < num_eps; i++) -		if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) -			return; +		if (!eps[i] || !eps[i]->streams) +			return -EINVAL; + +	ret = hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); +	if (ret < 0) +		return ret; -	hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); +	for (i = 0; i < num_eps; i++) +		eps[i]->streams = 0; + +	return ret;  }  EXPORT_SYMBOL_GPL(usb_free_streams); @@ -1912,7 +2142,7 @@ int usb_hcd_get_frame_number (struct usb_device *udev)  {  	struct usb_hcd	*hcd = bus_to_hcd(udev->bus); -	if (!HC_IS_RUNNING (hcd->state)) +	if (!HCD_RH_RUNNING(hcd))  		return -ESHUTDOWN;  	return hcd->driver->get_frame_number (hcd);  } @@ -1927,19 +2157,43 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)  	int		status;  	int		old_state = hcd->state; -	dev_dbg(&rhdev->dev, "bus %s%s\n", -			(msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); +	dev_dbg(&rhdev->dev, "bus %ssuspend, wakeup %d\n", +			(PMSG_IS_AUTO(msg) ? "auto-" : ""), +			rhdev->do_remote_wakeup); +	if (HCD_DEAD(hcd)) { +		dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend"); +		return 0; +	} +  	if (!hcd->driver->bus_suspend) {  		status = -ENOENT;  	} else { +		clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  		hcd->state = HC_STATE_QUIESCING;  		status = hcd->driver->bus_suspend(hcd);  	}  	if (status == 0) {  		usb_set_device_state(rhdev, USB_STATE_SUSPENDED);  		hcd->state = HC_STATE_SUSPENDED; + +		/* Did we race with a root-hub wakeup event? */ +		if (rhdev->do_remote_wakeup) { +			char	buffer[6]; + +			status = hcd->driver->hub_status_data(hcd, buffer); +			if (status != 0) { +				dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n"); +				hcd_bus_resume(rhdev, PMSG_AUTO_RESUME); +				status = -EBUSY; +			} +		}  	} else { -		hcd->state = old_state; +		spin_lock_irq(&hcd_root_hub_lock); +		if (!HCD_DEAD(hcd)) { +			set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); +			hcd->state = old_state; +		} +		spin_unlock_irq(&hcd_root_hub_lock);  		dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",  				"suspend", status);  	} @@ -1952,23 +2206,47 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)  	int		status;  	int		old_state = hcd->state; -	dev_dbg(&rhdev->dev, "usb %s%s\n", -			(msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); -	clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); +	dev_dbg(&rhdev->dev, "usb %sresume\n", +			(PMSG_IS_AUTO(msg) ? "auto-" : "")); +	if (HCD_DEAD(hcd)) { +		dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); +		return 0; +	}  	if (!hcd->driver->bus_resume)  		return -ENOENT; -	if (hcd->state == HC_STATE_RUNNING) +	if (HCD_RH_RUNNING(hcd))  		return 0;  	hcd->state = HC_STATE_RESUMING;  	status = hcd->driver->bus_resume(hcd); +	clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);  	if (status == 0) { -		/* TRSMRCY = 10 msec */ -		msleep(10); -		usb_set_device_state(rhdev, rhdev->actconfig -				? USB_STATE_CONFIGURED -				: USB_STATE_ADDRESS); -		hcd->state = HC_STATE_RUNNING; +		struct usb_device *udev; +		int port1; + +		spin_lock_irq(&hcd_root_hub_lock); +		if (!HCD_DEAD(hcd)) { +			usb_set_device_state(rhdev, rhdev->actconfig +					? USB_STATE_CONFIGURED +					: USB_STATE_ADDRESS); +			set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); +			hcd->state = HC_STATE_RUNNING; +		} +		spin_unlock_irq(&hcd_root_hub_lock); + +		/* +		 * Check whether any of the enabled ports on the root hub are +		 * unsuspended.  If they are then a TRSMRCY delay is needed +		 * (this is what the USB-2 spec calls a "global resume"). +		 * Otherwise we can skip the delay. +		 */ +		usb_hub_for_each_child(rhdev, port1, udev) { +			if (udev->state != USB_STATE_NOTATTACHED && +					!udev->port_is_suspended) { +				usleep_range(10000, 11000);	/* TRSMRCY */ +				break; +			} +		}  	} else {  		hcd->state = old_state;  		dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", @@ -1981,7 +2259,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)  #endif	/* CONFIG_PM */ -#ifdef	CONFIG_USB_SUSPEND +#ifdef	CONFIG_PM_RUNTIME  /* Workqueue routine for root-hub remote wakeup */  static void hcd_resume_work(struct work_struct *work) @@ -1989,13 +2267,11 @@ static void hcd_resume_work(struct work_struct *work)  	struct usb_hcd *hcd = container_of(work, struct usb_hcd, wakeup_work);  	struct usb_device *udev = hcd->self.root_hub; -	usb_lock_device(udev);  	usb_remote_wakeup(udev); -	usb_unlock_device(udev);  }  /** - * usb_hcd_resume_root_hub - called by HCD to resume its root hub  + * usb_hcd_resume_root_hub - called by HCD to resume its root hub   * @hcd: host controller for this root hub   *   * The USB host controller calls this function when its root hub is @@ -2016,7 +2292,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)  }  EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); -#endif	/* CONFIG_USB_SUSPEND */ +#endif	/* CONFIG_PM_RUNTIME */  /*-------------------------------------------------------------------------*/ @@ -2032,6 +2308,8 @@ EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);   * khubd identifying and possibly configuring the device.   * This is needed by OTG controller drivers, where it helps meet   * HNP protocol timing requirements for starting a port reset. + * + * Return: 0 if successful.   */  int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num)  { @@ -2066,32 +2344,21 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);   *   * If the controller isn't HALTed, calls the driver's irq handler.   * Checks whether the controller is now dead. + * + * Return: %IRQ_HANDLED if the IRQ was handled. %IRQ_NONE otherwise.   */  irqreturn_t usb_hcd_irq (int irq, void *__hcd)  {  	struct usb_hcd		*hcd = __hcd; -	unsigned long		flags;  	irqreturn_t		rc; -	/* IRQF_DISABLED doesn't work correctly with shared IRQs -	 * when the first handler doesn't use it.  So let's just -	 * assume it's never used. -	 */ -	local_irq_save(flags); - -	if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) { +	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))  		rc = IRQ_NONE; -	} else if (hcd->driver->irq(hcd) == IRQ_NONE) { +	else if (hcd->driver->irq(hcd) == IRQ_NONE)  		rc = IRQ_NONE; -	} else { -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - -		if (unlikely(hcd->state == HC_STATE_HALT)) -			usb_hc_died(hcd); +	else  		rc = IRQ_HANDLED; -	} -	local_irq_restore(flags);  	return rc;  }  EXPORT_SYMBOL_GPL(usb_hcd_irq); @@ -2104,7 +2371,9 @@ EXPORT_SYMBOL_GPL(usb_hcd_irq);   *   * This is called by bus glue to report a USB host controller that died   * while operations may still have been pending.  It's called automatically - * by the PCI glue, so only glue for non-PCI busses should need to call it.  + * by the PCI glue, so only glue for non-PCI busses should need to call it. + * + * Only call this function with the primary HCD.   */  void usb_hc_died (struct usb_hcd *hcd)  { @@ -2113,6 +2382,8 @@ void usb_hc_died (struct usb_hcd *hcd)  	dev_err (hcd->self.controller, "HC died; cleaning up\n");  	spin_lock_irqsave (&hcd_root_hub_lock, flags); +	clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); +	set_bit(HCD_FLAG_DEAD, &hcd->flags);  	if (hcd->rh_registered) {  		clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); @@ -2121,27 +2392,51 @@ void usb_hc_died (struct usb_hcd *hcd)  				USB_STATE_NOTATTACHED);  		usb_kick_khubd (hcd->self.root_hub);  	} +	if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) { +		hcd = hcd->shared_hcd; +		if (hcd->rh_registered) { +			clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + +			/* make khubd clean up old urbs and devices */ +			usb_set_device_state(hcd->self.root_hub, +					USB_STATE_NOTATTACHED); +			usb_kick_khubd(hcd->self.root_hub); +		} +	}  	spin_unlock_irqrestore (&hcd_root_hub_lock, flags); +	/* Make sure that the other roothub is also deallocated. */  }  EXPORT_SYMBOL_GPL (usb_hc_died);  /*-------------------------------------------------------------------------*/ +static void init_giveback_urb_bh(struct giveback_urb_bh *bh) +{ + +	spin_lock_init(&bh->lock); +	INIT_LIST_HEAD(&bh->head); +	tasklet_init(&bh->bh, usb_giveback_urb_bh, (unsigned long)bh); +} +  /** - * usb_create_hcd - create and initialize an HCD structure + * usb_create_shared_hcd - create and initialize an HCD structure   * @driver: HC driver that will use this hcd   * @dev: device for this HC, stored in hcd->self.controller   * @bus_name: value to store in hcd->self.bus_name + * @primary_hcd: a pointer to the usb_hcd structure that is sharing the + *              PCI device.  Only allocate certain resources for the primary HCD   * Context: !in_interrupt()   *   * Allocate a struct usb_hcd, with extra space at the end for the   * HC driver's private data.  Initialize the generic members of the   * hcd structure.   * - * If memory is unavailable, returns NULL. + * Return: On success, a pointer to the created and initialized HCD structure. + * On failure (e.g. if memory is unavailable), %NULL.   */ -struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, -		struct device *dev, const char *bus_name) +struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, +		struct device *dev, const char *bus_name, +		struct usb_hcd *primary_hcd)  {  	struct usb_hcd *hcd; @@ -2150,7 +2445,26 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,  		dev_dbg (dev, "hcd alloc failed\n");  		return NULL;  	} -	dev_set_drvdata(dev, hcd); +	if (primary_hcd == NULL) { +		hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), +				GFP_KERNEL); +		if (!hcd->bandwidth_mutex) { +			kfree(hcd); +			dev_dbg(dev, "hcd bandwidth mutex alloc failed\n"); +			return NULL; +		} +		mutex_init(hcd->bandwidth_mutex); +		dev_set_drvdata(dev, hcd); +	} else { +		mutex_lock(&usb_port_peer_mutex); +		hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex; +		hcd->primary_hcd = primary_hcd; +		primary_hcd->primary_hcd = primary_hcd; +		hcd->shared_hcd = primary_hcd; +		primary_hcd->shared_hcd = hcd; +		mutex_unlock(&usb_port_peer_mutex); +	} +  	kref_init(&hcd->kref);  	usb_bus_init(&hcd->self); @@ -2161,22 +2475,64 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,  	init_timer(&hcd->rh_timer);  	hcd->rh_timer.function = rh_timer_func;  	hcd->rh_timer.data = (unsigned long) hcd; -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME  	INIT_WORK(&hcd->wakeup_work, hcd_resume_work);  #endif -	mutex_init(&hcd->bandwidth_mutex);  	hcd->driver = driver; +	hcd->speed = driver->flags & HCD_MASK;  	hcd->product_desc = (driver->product_desc) ? driver->product_desc :  			"USB Host Controller";  	return hcd;  } +EXPORT_SYMBOL_GPL(usb_create_shared_hcd); + +/** + * usb_create_hcd - create and initialize an HCD structure + * @driver: HC driver that will use this hcd + * @dev: device for this HC, stored in hcd->self.controller + * @bus_name: value to store in hcd->self.bus_name + * Context: !in_interrupt() + * + * Allocate a struct usb_hcd, with extra space at the end for the + * HC driver's private data.  Initialize the generic members of the + * hcd structure. + * + * Return: On success, a pointer to the created and initialized HCD + * structure. On failure (e.g. if memory is unavailable), %NULL. + */ +struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, +		struct device *dev, const char *bus_name) +{ +	return usb_create_shared_hcd(driver, dev, bus_name, NULL); +}  EXPORT_SYMBOL_GPL(usb_create_hcd); -static void hcd_release (struct kref *kref) +/* + * Roothubs that share one PCI device must also share the bandwidth mutex. + * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is + * deallocated. + * + * Make sure to only deallocate the bandwidth_mutex when the primary HCD is + * freed.  When hcd_release() is called for either hcd in a peer set + * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to + * block new peering attempts + */ +static void hcd_release(struct kref *kref)  {  	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); +	mutex_lock(&usb_port_peer_mutex); +	if (usb_hcd_is_primary_hcd(hcd)) +		kfree(hcd->bandwidth_mutex); +	if (hcd->shared_hcd) { +		struct usb_hcd *peer = hcd->shared_hcd; + +		peer->shared_hcd = NULL; +		if (peer->primary_hcd == hcd) +			peer->primary_hcd = NULL; +	} +	mutex_unlock(&usb_port_peer_mutex);  	kfree(hcd);  } @@ -2195,6 +2551,70 @@ void usb_put_hcd (struct usb_hcd *hcd)  }  EXPORT_SYMBOL_GPL(usb_put_hcd); +int usb_hcd_is_primary_hcd(struct usb_hcd *hcd) +{ +	if (!hcd->primary_hcd) +		return 1; +	return hcd == hcd->primary_hcd; +} +EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd); + +int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1) +{ +	if (!hcd->driver->find_raw_port_number) +		return port1; + +	return hcd->driver->find_raw_port_number(hcd, port1); +} + +static int usb_hcd_request_irqs(struct usb_hcd *hcd, +		unsigned int irqnum, unsigned long irqflags) +{ +	int retval; + +	if (hcd->driver->irq) { + +		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", +				hcd->driver->description, hcd->self.busnum); +		retval = request_irq(irqnum, &usb_hcd_irq, irqflags, +				hcd->irq_descr, hcd); +		if (retval != 0) { +			dev_err(hcd->self.controller, +					"request interrupt %d failed\n", +					irqnum); +			return retval; +		} +		hcd->irq = irqnum; +		dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, +				(hcd->driver->flags & HCD_MEMORY) ? +					"io mem" : "io base", +					(unsigned long long)hcd->rsrc_start); +	} else { +		hcd->irq = 0; +		if (hcd->rsrc_start) +			dev_info(hcd->self.controller, "%s 0x%08llx\n", +					(hcd->driver->flags & HCD_MEMORY) ? +					"io mem" : "io base", +					(unsigned long long)hcd->rsrc_start); +	} +	return 0; +} + +/* + * Before we free this root hub, flush in-flight peering attempts + * and disable peer lookups + */ +static void usb_put_invalidate_rhdev(struct usb_hcd *hcd) +{ +	struct usb_device *rhdev; + +	mutex_lock(&usb_port_peer_mutex); +	rhdev = hcd->self.root_hub; +	hcd->self.root_hub = NULL; +	mutex_unlock(&usb_port_peer_mutex); +	usb_put_dev(rhdev); +} +  /**   * usb_add_hcd - finish generic HCD structure initialization and register   * @hcd: the usb_hcd structure to initialize @@ -2211,9 +2631,31 @@ int usb_add_hcd(struct usb_hcd *hcd,  	int retval;  	struct usb_device *rhdev; +	if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->phy) { +		struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0); + +		if (IS_ERR(phy)) { +			retval = PTR_ERR(phy); +			if (retval == -EPROBE_DEFER) +				return retval; +		} else { +			retval = usb_phy_init(phy); +			if (retval) { +				usb_put_phy(phy); +				return retval; +			} +			hcd->phy = phy; +			hcd->remove_phy = 1; +		} +	} +  	dev_info(hcd->self.controller, "%s\n", hcd->product_desc); -	hcd->authorized_default = hcd->wireless? 0 : 1; +	/* Keep old behaviour if authorized_default is not in [0, 1]. */ +	if (authorized_default < 0 || authorized_default > 1) +		hcd->authorized_default = hcd->wireless ? 0 : 1; +	else +		hcd->authorized_default = authorized_default;  	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);  	/* HC is in reset state, but accessible.  Now do the one-time init, @@ -2222,7 +2664,7 @@ int usb_add_hcd(struct usb_hcd *hcd,  	 */  	if ((retval = hcd_buffer_create(hcd)) != 0) {  		dev_dbg(hcd->self.controller, "pool alloc failed\n"); -		return retval; +		goto err_remove_phy;  	}  	if ((retval = usb_register_bus(&hcd->self)) < 0) @@ -2233,19 +2675,25 @@ int usb_add_hcd(struct usb_hcd *hcd,  		retval = -ENOMEM;  		goto err_allocate_root_hub;  	} +	mutex_lock(&usb_port_peer_mutex);  	hcd->self.root_hub = rhdev; +	mutex_unlock(&usb_port_peer_mutex); -	switch (hcd->driver->flags & HCD_MASK) { +	switch (hcd->speed) {  	case HCD_USB11:  		rhdev->speed = USB_SPEED_FULL;  		break;  	case HCD_USB2:  		rhdev->speed = USB_SPEED_HIGH;  		break; +	case HCD_USB25: +		rhdev->speed = USB_SPEED_WIRELESS; +		break;  	case HCD_USB3:  		rhdev->speed = USB_SPEED_SUPER;  		break;  	default: +		retval = -EINVAL;  		goto err_set_rh_speed;  	} @@ -2253,13 +2701,19 @@ int usb_add_hcd(struct usb_hcd *hcd,  	 * but drivers can override it in reset() if needed, along with  	 * recording the overall controller's system wakeup capability.  	 */ -	device_init_wakeup(&rhdev->dev, 1); +	device_set_wakeup_capable(&rhdev->dev, 1); + +	/* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is +	 * registered.  But since the controller can die at any time, +	 * let's initialize the flag before touching the hardware. +	 */ +	set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  	/* "reset" is misnamed; its role is now one-time init. the controller  	 * should already have been reset (and boot firmware kicked off etc).  	 */  	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { -		dev_err(hcd->self.controller, "can't setup\n"); +		dev_err(hcd->self.controller, "can't setup: %d\n", retval);  		goto err_hcd_driver_setup;  	}  	hcd->rh_pollable = 1; @@ -2269,45 +2723,27 @@ int usb_add_hcd(struct usb_hcd *hcd,  			&& device_can_wakeup(&hcd->self.root_hub->dev))  		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); -	/* enable irqs just before we start the controller */ -	if (hcd->driver->irq) { - -		/* IRQF_DISABLED doesn't work as advertised when used together -		 * with IRQF_SHARED. As usb_hcd_irq() will always disable -		 * interrupts we can remove it here. -		 */ -		if (irqflags & IRQF_SHARED) -			irqflags &= ~IRQF_DISABLED; +	/* initialize tasklets */ +	init_giveback_urb_bh(&hcd->high_prio_bh); +	init_giveback_urb_bh(&hcd->low_prio_bh); -		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", -				hcd->driver->description, hcd->self.busnum); -		if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, -				hcd->irq_descr, hcd)) != 0) { -			dev_err(hcd->self.controller, -					"request interrupt %d failed\n", irqnum); +	/* enable irqs just before we start the controller, +	 * if the BIOS provides legacy PCI irqs. +	 */ +	if (usb_hcd_is_primary_hcd(hcd) && irqnum) { +		retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); +		if (retval)  			goto err_request_irq; -		} -		hcd->irq = irqnum; -		dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, -				(hcd->driver->flags & HCD_MEMORY) ? -					"io mem" : "io base", -					(unsigned long long)hcd->rsrc_start); -	} else { -		hcd->irq = -1; -		if (hcd->rsrc_start) -			dev_info(hcd->self.controller, "%s 0x%08llx\n", -					(hcd->driver->flags & HCD_MEMORY) ? -					"io mem" : "io base", -					(unsigned long long)hcd->rsrc_start);  	} -	if ((retval = hcd->driver->start(hcd)) < 0) { +	hcd->state = HC_STATE_RUNNING; +	retval = hcd->driver->start(hcd); +	if (retval < 0) {  		dev_err(hcd->self.controller, "startup error %d\n", retval);  		goto err_hcd_driver_start;  	}  	/* starting here, usbcore will pay attention to this root hub */ -	rhdev->bus_mA = min(500u, hcd->power_budget);  	if ((retval = register_root_hub(hcd)) != 0)  		goto err_register_root_hub; @@ -2319,16 +2755,18 @@ int usb_add_hcd(struct usb_hcd *hcd,  	}  	if (hcd->uses_new_polling && HCD_POLL_RH(hcd))  		usb_hcd_poll_rh_status(hcd); +  	return retval;  error_create_attr_group: +	clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  	if (HC_IS_RUNNING(hcd->state))  		hcd->state = HC_STATE_QUIESCING;  	spin_lock_irq(&hcd_root_hub_lock);  	hcd->rh_registered = 0;  	spin_unlock_irq(&hcd_root_hub_lock); -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME  	cancel_work_sync(&hcd->wakeup_work);  #endif  	mutex_lock(&usb_bus_list_lock); @@ -2343,18 +2781,24 @@ err_register_root_hub:  	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);  	del_timer_sync(&hcd->rh_timer);  err_hcd_driver_start: -	if (hcd->irq >= 0) +	if (usb_hcd_is_primary_hcd(hcd) && hcd->irq > 0)  		free_irq(irqnum, hcd);  err_request_irq:  err_hcd_driver_setup:  err_set_rh_speed: -	usb_put_dev(hcd->self.root_hub); +	usb_put_invalidate_rhdev(hcd);  err_allocate_root_hub:  	usb_deregister_bus(&hcd->self);  err_register_bus:  	hcd_buffer_destroy(hcd); +err_remove_phy: +	if (hcd->remove_phy && hcd->phy) { +		usb_phy_shutdown(hcd->phy); +		usb_put_phy(hcd->phy); +		hcd->phy = NULL; +	}  	return retval; -}  +}  EXPORT_SYMBOL_GPL(usb_add_hcd);  /** @@ -2374,6 +2818,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)  	usb_get_dev(rhdev);  	sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); +	clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  	if (HC_IS_RUNNING (hcd->state))  		hcd->state = HC_STATE_QUIESCING; @@ -2382,7 +2827,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)  	hcd->rh_registered = 0;  	spin_unlock_irq (&hcd_root_hub_lock); -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME  	cancel_work_sync(&hcd->wakeup_work);  #endif @@ -2390,6 +2835,16 @@ void usb_remove_hcd(struct usb_hcd *hcd)  	usb_disconnect(&rhdev);		/* Sets rhdev to NULL */  	mutex_unlock(&usb_bus_list_lock); +	/* +	 * tasklet_kill() isn't needed here because: +	 * - driver's disconnect() called from usb_disconnect() should +	 *   make sure its URBs are completed during the disconnect() +	 *   callback +	 * +	 * - it is too late to run complete() here since driver may have +	 *   been removed already now +	 */ +  	/* Prevent any more root-hub status calls from the timer.  	 * The HCD might still restart the timer (if a port status change  	 * interrupt occurs), but usb_hcd_poll_rh_status() won't invoke @@ -2406,17 +2861,25 @@ void usb_remove_hcd(struct usb_hcd *hcd)  	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);  	del_timer_sync(&hcd->rh_timer); -	if (hcd->irq >= 0) -		free_irq(hcd->irq, hcd); +	if (usb_hcd_is_primary_hcd(hcd)) { +		if (hcd->irq > 0) +			free_irq(hcd->irq, hcd); +	} -	usb_put_dev(hcd->self.root_hub);  	usb_deregister_bus(&hcd->self);  	hcd_buffer_destroy(hcd); +	if (hcd->remove_phy && hcd->phy) { +		usb_phy_shutdown(hcd->phy); +		usb_put_phy(hcd->phy); +		hcd->phy = NULL; +	} + +	usb_put_invalidate_rhdev(hcd);  }  EXPORT_SYMBOL_GPL(usb_remove_hcd);  void -usb_hcd_platform_shutdown(struct platform_device* dev) +usb_hcd_platform_shutdown(struct platform_device *dev)  {  	struct usb_hcd *hcd = platform_get_drvdata(dev); @@ -2438,7 +2901,7 @@ struct usb_mon_operations *mon_ops;   * Notice that the code is minimally error-proof. Because usbmon needs   * symbols from usbcore, usbcore gets referenced and cannot be unloaded first.   */ -  +  int usb_mon_register (struct usb_mon_operations *ops)  { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 27115b45edc..0e950ad8cb2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -20,69 +20,21 @@  #include <linux/usb.h>  #include <linux/usbdevice_fs.h>  #include <linux/usb/hcd.h> +#include <linux/usb/otg.h>  #include <linux/usb/quirks.h>  #include <linux/kthread.h>  #include <linux/mutex.h>  #include <linux/freezer.h> -#include <linux/pm_runtime.h> +#include <linux/random.h> +#include <linux/pm_qos.h>  #include <asm/uaccess.h>  #include <asm/byteorder.h> -#include "usb.h" - -/* if we are in debug mode, always announce new devices */ -#ifdef DEBUG -#ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES -#define CONFIG_USB_ANNOUNCE_NEW_DEVICES -#endif -#endif - -struct usb_hub { -	struct device		*intfdev;	/* the "interface" device */ -	struct usb_device	*hdev; -	struct kref		kref; -	struct urb		*urb;		/* for interrupt polling pipe */ - -	/* buffer for urb ... with extra space in case of babble */ -	char			(*buffer)[8]; -	union { -		struct usb_hub_status	hub; -		struct usb_port_status	port; -	}			*status;	/* buffer for status reports */ -	struct mutex		status_mutex;	/* for the status buffer */ - -	int			error;		/* last reported error */ -	int			nerrors;	/* track consecutive errors */ - -	struct list_head	event_list;	/* hubs w/data or errs ready */ -	unsigned long		event_bits[1];	/* status change bitmask */ -	unsigned long		change_bits[1];	/* ports with logical connect -							status change */ -	unsigned long		busy_bits[1];	/* ports being reset or -							resumed */ -	unsigned long		removed_bits[1]; /* ports with a "removed" -							device present */ -#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ -#error event_bits[] is too short! -#endif - -	struct usb_hub_descriptor *descriptor;	/* class descriptor */ -	struct usb_tt		tt;		/* Transaction Translator */ - -	unsigned		mA_per_port;	/* current for each child */ - -	unsigned		limited_power:1; -	unsigned		quiescing:1; -	unsigned		disconnected:1; - -	unsigned		has_indicators:1; -	u8			indicator[USB_MAXCHILDREN]; -	struct delayed_work	leds; -	struct delayed_work	init_work; -	void			**port_owners; -}; +#include "hub.h" +#define USB_VENDOR_GENESYS_LOGIC		0x05e3 +#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND	0x01  /* Protect struct usb_device->state and ->children members   * Note: Both are also protected by ->dev.sem, except that ->state can @@ -98,8 +50,11 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);  static struct task_struct *khubd_task; +/* synchronize hub-port add/remove and peering operations */ +DEFINE_MUTEX(usb_port_peer_mutex); +  /* cycle leds on hubs that aren't blinking for attention */ -static int blinkenlights = 0; +static bool blinkenlights = 0;  module_param (blinkenlights, bool, S_IRUGO);  MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs"); @@ -128,12 +83,12 @@ MODULE_PARM_DESC(initial_descriptor_timeout,   * otherwise the new scheme is used.  If that fails and "use_both_schemes"   * is set, then the driver will make another attempt, using the other scheme.   */ -static int old_scheme_first = 0; +static bool old_scheme_first = 0;  module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(old_scheme_first,  		 "start with the old device initialization scheme"); -static int use_both_schemes = 1; +static bool use_both_schemes = 1;  module_param(use_both_schemes, bool, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(use_both_schemes,  		"try the other device initialization scheme if the " @@ -145,42 +100,280 @@ MODULE_PARM_DESC(use_both_schemes,  DECLARE_RWSEM(ehci_cf_port_reset_rwsem);  EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); -#define HUB_DEBOUNCE_TIMEOUT	1500 +#define HUB_DEBOUNCE_TIMEOUT	2000  #define HUB_DEBOUNCE_STEP	  25  #define HUB_DEBOUNCE_STABLE	 100 -  static int usb_reset_and_verify_device(struct usb_device *udev); -static inline char *portspeed(int portstatus) +static inline char *portspeed(struct usb_hub *hub, int portstatus)  { +	if (hub_is_superspeed(hub->hdev)) +		return "5.0 Gb/s";  	if (portstatus & USB_PORT_STAT_HIGH_SPEED) -    		return "480 Mb/s"; +		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";  }  /* Note that hdev or one of its children must be locked! */ -static struct usb_hub *hdev_to_hub(struct usb_device *hdev) +struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)  { -	if (!hdev || !hdev->actconfig) +	if (!hdev || !hdev->actconfig || !hdev->maxchild)  		return NULL;  	return usb_get_intfdata(hdev->actconfig->interface[0]);  } +static int usb_device_supports_lpm(struct usb_device *udev) +{ +	/* USB 2.1 (and greater) devices indicate LPM support through +	 * their USB 2.0 Extended Capabilities BOS descriptor. +	 */ +	if (udev->speed == USB_SPEED_HIGH) { +		if (udev->bos->ext_cap && +			(USB_LPM_SUPPORT & +			 le32_to_cpu(udev->bos->ext_cap->bmAttributes))) +			return 1; +		return 0; +	} + +	/* +	 * According to the USB 3.0 spec, all USB 3.0 devices must support LPM. +	 * However, there are some that don't, and they set the U1/U2 exit +	 * latencies to zero. +	 */ +	if (!udev->bos->ss_cap) { +		dev_info(&udev->dev, "No LPM exit latency info found, disabling LPM.\n"); +		return 0; +	} + +	if (udev->bos->ss_cap->bU1devExitLat == 0 && +			udev->bos->ss_cap->bU2DevExitLat == 0) { +		if (udev->parent) +			dev_info(&udev->dev, "LPM exit latency is zeroed, disabling LPM.\n"); +		else +			dev_info(&udev->dev, "We don't know the algorithms for LPM for this host, disabling LPM.\n"); +		return 0; +	} + +	if (!udev->parent || udev->parent->lpm_capable) +		return 1; +	return 0; +} + +/* + * Set the Maximum Exit Latency (MEL) for the host to initiate a transition from + * either U1 or U2. + */ +static void usb_set_lpm_mel(struct usb_device *udev, +		struct usb3_lpm_parameters *udev_lpm_params, +		unsigned int udev_exit_latency, +		struct usb_hub *hub, +		struct usb3_lpm_parameters *hub_lpm_params, +		unsigned int hub_exit_latency) +{ +	unsigned int total_mel; +	unsigned int device_mel; +	unsigned int hub_mel; + +	/* +	 * Calculate the time it takes to transition all links from the roothub +	 * to the parent hub into U0.  The parent hub must then decode the +	 * packet (hub header decode latency) to figure out which port it was +	 * bound for. +	 * +	 * The Hub Header decode latency is expressed in 0.1us intervals (0x1 +	 * means 0.1us).  Multiply that by 100 to get nanoseconds. +	 */ +	total_mel = hub_lpm_params->mel + +		(hub->descriptor->u.ss.bHubHdrDecLat * 100); + +	/* +	 * How long will it take to transition the downstream hub's port into +	 * U0?  The greater of either the hub exit latency or the device exit +	 * latency. +	 * +	 * The BOS U1/U2 exit latencies are expressed in 1us intervals. +	 * Multiply that by 1000 to get nanoseconds. +	 */ +	device_mel = udev_exit_latency * 1000; +	hub_mel = hub_exit_latency * 1000; +	if (device_mel > hub_mel) +		total_mel += device_mel; +	else +		total_mel += hub_mel; + +	udev_lpm_params->mel = total_mel; +} + +/* + * Set the maximum Device to Host Exit Latency (PEL) for the device to initiate + * a transition from either U1 or U2. + */ +static void usb_set_lpm_pel(struct usb_device *udev, +		struct usb3_lpm_parameters *udev_lpm_params, +		unsigned int udev_exit_latency, +		struct usb_hub *hub, +		struct usb3_lpm_parameters *hub_lpm_params, +		unsigned int hub_exit_latency, +		unsigned int port_to_port_exit_latency) +{ +	unsigned int first_link_pel; +	unsigned int hub_pel; + +	/* +	 * First, the device sends an LFPS to transition the link between the +	 * device and the parent hub into U0.  The exit latency is the bigger of +	 * the device exit latency or the hub exit latency. +	 */ +	if (udev_exit_latency > hub_exit_latency) +		first_link_pel = udev_exit_latency * 1000; +	else +		first_link_pel = hub_exit_latency * 1000; + +	/* +	 * When the hub starts to receive the LFPS, there is a slight delay for +	 * it to figure out that one of the ports is sending an LFPS.  Then it +	 * will forward the LFPS to its upstream link.  The exit latency is the +	 * delay, plus the PEL that we calculated for this hub. +	 */ +	hub_pel = port_to_port_exit_latency * 1000 + hub_lpm_params->pel; + +	/* +	 * According to figure C-7 in the USB 3.0 spec, the PEL for this device +	 * is the greater of the two exit latencies. +	 */ +	if (first_link_pel > hub_pel) +		udev_lpm_params->pel = first_link_pel; +	else +		udev_lpm_params->pel = hub_pel; +} + +/* + * Set the System Exit Latency (SEL) to indicate the total worst-case time from + * when a device initiates a transition to U0, until when it will receive the + * first packet from the host controller. + * + * Section C.1.5.1 describes the four components to this: + *  - t1: device PEL + *  - t2: time for the ERDY to make it from the device to the host. + *  - t3: a host-specific delay to process the ERDY. + *  - t4: time for the packet to make it from the host to the device. + * + * t3 is specific to both the xHCI host and the platform the host is integrated + * into.  The Intel HW folks have said it's negligible, FIXME if a different + * vendor says otherwise. + */ +static void usb_set_lpm_sel(struct usb_device *udev, +		struct usb3_lpm_parameters *udev_lpm_params) +{ +	struct usb_device *parent; +	unsigned int num_hubs; +	unsigned int total_sel; + +	/* t1 = device PEL */ +	total_sel = udev_lpm_params->pel; +	/* How many external hubs are in between the device & the root port. */ +	for (parent = udev->parent, num_hubs = 0; parent->parent; +			parent = parent->parent) +		num_hubs++; +	/* t2 = 2.1us + 250ns * (num_hubs - 1) */ +	if (num_hubs > 0) +		total_sel += 2100 + 250 * (num_hubs - 1); + +	/* t4 = 250ns * num_hubs */ +	total_sel += 250 * num_hubs; + +	udev_lpm_params->sel = total_sel; +} + +static void usb_set_lpm_parameters(struct usb_device *udev) +{ +	struct usb_hub *hub; +	unsigned int port_to_port_delay; +	unsigned int udev_u1_del; +	unsigned int udev_u2_del; +	unsigned int hub_u1_del; +	unsigned int hub_u2_del; + +	if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER) +		return; + +	hub = usb_hub_to_struct_hub(udev->parent); +	/* It doesn't take time to transition the roothub into U0, since it +	 * doesn't have an upstream link. +	 */ +	if (!hub) +		return; + +	udev_u1_del = udev->bos->ss_cap->bU1devExitLat; +	udev_u2_del = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat); +	hub_u1_del = udev->parent->bos->ss_cap->bU1devExitLat; +	hub_u2_del = le16_to_cpu(udev->parent->bos->ss_cap->bU2DevExitLat); + +	usb_set_lpm_mel(udev, &udev->u1_params, udev_u1_del, +			hub, &udev->parent->u1_params, hub_u1_del); + +	usb_set_lpm_mel(udev, &udev->u2_params, udev_u2_del, +			hub, &udev->parent->u2_params, hub_u2_del); + +	/* +	 * Appendix C, section C.2.2.2, says that there is a slight delay from +	 * when the parent hub notices the downstream port is trying to +	 * transition to U0 to when the hub initiates a U0 transition on its +	 * upstream port.  The section says the delays are tPort2PortU1EL and +	 * tPort2PortU2EL, but it doesn't define what they are. +	 * +	 * The hub chapter, sections 10.4.2.4 and 10.4.2.5 seem to be talking +	 * about the same delays.  Use the maximum delay calculations from those +	 * sections.  For U1, it's tHubPort2PortExitLat, which is 1us max.  For +	 * U2, it's tHubPort2PortExitLat + U2DevExitLat - U1DevExitLat.  I +	 * assume the device exit latencies they are talking about are the hub +	 * exit latencies. +	 * +	 * What do we do if the U2 exit latency is less than the U1 exit +	 * latency?  It's possible, although not likely... +	 */ +	port_to_port_delay = 1; + +	usb_set_lpm_pel(udev, &udev->u1_params, udev_u1_del, +			hub, &udev->parent->u1_params, hub_u1_del, +			port_to_port_delay); + +	if (hub_u2_del > hub_u1_del) +		port_to_port_delay = 1 + hub_u2_del - hub_u1_del; +	else +		port_to_port_delay = 1 + hub_u1_del; + +	usb_set_lpm_pel(udev, &udev->u2_params, udev_u2_del, +			hub, &udev->parent->u2_params, hub_u2_del, +			port_to_port_delay); + +	/* Now that we've got PEL, calculate SEL. */ +	usb_set_lpm_sel(udev, &udev->u1_params); +	usb_set_lpm_sel(udev, &udev->u2_params); +} +  /* USB 2.0 spec Section 11.24.4.5 */ -static int get_hub_descriptor(struct usb_device *hdev, void *data, int size) +static int get_hub_descriptor(struct usb_device *hdev, void *data)  { -	int i, ret; +	int i, ret, size; +	unsigned dtype; + +	if (hub_is_superspeed(hdev)) { +		dtype = USB_DT_SS_HUB; +		size = USB_DT_SS_HUB_SIZE; +	} else { +		dtype = USB_DT_HUB; +		size = sizeof(struct usb_hub_descriptor); +	}  	for (i = 0; i < 3; i++) {  		ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),  			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, -			USB_DT_HUB << 8, 0, data, size, +			dtype << 8, 0, data, size,  			USB_CTRL_GET_TIMEOUT);  		if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))  			return ret; @@ -200,7 +393,7 @@ static int clear_hub_feature(struct usb_device *hdev, int feature)  /*   * USB 2.0 spec Section 11.24.2.2   */ -static int clear_port_feature(struct usb_device *hdev, int port1, int feature) +int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)  {  	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),  		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, @@ -217,30 +410,35 @@ static int set_port_feature(struct usb_device *hdev, int port1, int feature)  		NULL, 0, 1000);  } +static char *to_led_name(int selector) +{ +	switch (selector) { +	case HUB_LED_AMBER: +		return "amber"; +	case HUB_LED_GREEN: +		return "green"; +	case HUB_LED_OFF: +		return "off"; +	case HUB_LED_AUTO: +		return "auto"; +	default: +		return "??"; +	} +} +  /*   * USB 2.0 spec Section 11.24.2.7.1.10 and table 11-7   * for info about using port indicators   */ -static void set_port_led( -	struct usb_hub *hub, -	int port1, -	int selector -) +static void set_port_led(struct usb_hub *hub, int port1, int selector)  { -	int status = set_port_feature(hub->hdev, (selector << 8) | port1, +	struct usb_port *port_dev = hub->ports[port1 - 1]; +	int status; + +	status = set_port_feature(hub->hdev, (selector << 8) | port1,  			USB_PORT_FEAT_INDICATOR); -	if (status < 0) -		dev_dbg (hub->intfdev, -			"port %d indicator %s status %d\n", -			port1, -			({ char *s; switch (selector) { -			case HUB_LED_AMBER: s = "amber"; break; -			case HUB_LED_GREEN: s = "green"; break; -			case HUB_LED_OFF: s = "off"; break; -			case HUB_LED_AUTO: s = "auto"; break; -			default: s = "??"; break; -			}; s; }), -			status); +	dev_dbg(&port_dev->dev, "indicator %s status %d\n", +		to_led_name(selector), status);  }  #define	LED_CYCLE_PERIOD	((2*HZ)/3) @@ -257,7 +455,7 @@ static void led_work (struct work_struct *work)  	if (hdev->state != USB_STATE_CONFIGURED || hub->quiescing)  		return; -	for (i = 0; i < hub->descriptor->bNbrPorts; i++) { +	for (i = 0; i < hdev->maxchild; i++) {  		unsigned	selector, mode;  		/* 30%-50% duty cycle */ @@ -306,13 +504,14 @@ static void led_work (struct work_struct *work)  	}  	if (!changed && blinkenlights) {  		cursor++; -		cursor %= hub->descriptor->bNbrPorts; +		cursor %= hdev->maxchild;  		set_port_led(hub, cursor + 1, HUB_LED_GREEN);  		hub->indicator[cursor] = INDICATOR_CYCLE;  		changed++;  	}  	if (changed) -		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); +		queue_delayed_work(system_power_efficient_wq, +				&hub->leds, LED_CYCLE_PERIOD);  }  /* use a short timeout for hub/port status fetches */ @@ -327,7 +526,8 @@ static int get_hub_status(struct usb_device *hdev,  {  	int i, status = -ETIMEDOUT; -	for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) { +	for (i = 0; i < USB_STS_RETRIES && +			(status == -ETIMEDOUT || status == -EPIPE); i++) {  		status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),  			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,  			data, sizeof(*data), USB_STS_TIMEOUT); @@ -343,7 +543,8 @@ static int get_port_status(struct usb_device *hdev, int port1,  {  	int i, status = -ETIMEDOUT; -	for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) { +	for (i = 0; i < USB_STS_RETRIES && +			(status == -ETIMEDOUT || status == -EPIPE); i++) {  		status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),  			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,  			data, sizeof(*data), USB_STS_TIMEOUT); @@ -359,13 +560,15 @@ static int hub_port_status(struct usb_hub *hub, int port1,  	mutex_lock(&hub->status_mutex);  	ret = get_port_status(hub->hdev, port1, &hub->status->port);  	if (ret < 4) { -		dev_err(hub->intfdev, -			"%s failed (err = %d)\n", __func__, ret); +		if (ret != -ENODEV) +			dev_err(hub->intfdev, +				"%s failed (err = %d)\n", __func__, ret);  		if (ret >= 0)  			ret = -EIO;  	} else {  		*status = le16_to_cpu(hub->status->port.wPortStatus);  		*change = le16_to_cpu(hub->status->port.wPortChange); +  		ret = 0;  	}  	mutex_unlock(&hub->status_mutex); @@ -390,12 +593,35 @@ static void kick_khubd(struct usb_hub *hub)  void usb_kick_khubd(struct usb_device *hdev)  { -	struct usb_hub *hub = hdev_to_hub(hdev); +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);  	if (hub)  		kick_khubd(hub);  } +/* + * Let the USB core know that a USB 3.0 device has sent a Function Wake Device + * Notification, which indicates it had initiated remote wakeup. + * + * USB 3.0 hubs do not report the port link state change from U3 to U0 when the + * device initiates resume, so the USB core will not receive notice of the + * resume through the normal hub interrupt URB. + */ +void usb_wakeup_notification(struct usb_device *hdev, +		unsigned int portnum) +{ +	struct usb_hub *hub; + +	if (!hdev) +		return; + +	hub = usb_hub_to_struct_hub(hdev); +	if (hub) { +		set_bit(portnum, hub->wakeup_bits); +		kick_khubd(hub); +	} +} +EXPORT_SYMBOL_GPL(usb_wakeup_notification);  /* completion function, fires on port status changes and various faults */  static void hub_irq(struct urb *urb) @@ -447,6 +673,15 @@ resubmit:  static inline int  hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)  { +	/* Need to clear both directions for control ep */ +	if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) == +			USB_ENDPOINT_XFER_CONTROL) { +		int status = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), +				HUB_CLEAR_TT_BUFFER, USB_RT_PORT, +				devinfo ^ 0x8000, tt, NULL, 0, 1000); +		if (status) +			return status; +	}  	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),  			       HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,  			       tt, NULL, 0, 1000); @@ -463,10 +698,9 @@ static void hub_tt_work(struct work_struct *work)  	struct usb_hub		*hub =  		container_of(work, struct usb_hub, tt.clear_work);  	unsigned long		flags; -	int			limit = 100;  	spin_lock_irqsave (&hub->tt.lock, flags); -	while (--limit && !list_empty (&hub->tt.clear_list)) { +	while (!list_empty(&hub->tt.clear_list)) {  		struct list_head	*next;  		struct usb_tt_clear	*clear;  		struct usb_device	*hdev = hub->hdev; @@ -480,7 +714,7 @@ static void hub_tt_work(struct work_struct *work)  		/* drop lock so HCD can concurrently report other TT errors */  		spin_unlock_irqrestore (&hub->tt.lock, flags);  		status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); -		if (status) +		if (status && status != -ENODEV)  			dev_err (&hdev->dev,  				"clear tt %d (%04x) error %d\n",  				clear->tt, clear->devinfo, status); @@ -497,6 +731,38 @@ static void hub_tt_work(struct work_struct *work)  }  /** + * usb_hub_set_port_power - control hub port's power state + * @hdev: USB device belonging to the usb hub + * @hub: target hub + * @port1: port index + * @set: expected status + * + * call this function to control port's power via setting or + * clearing the port's PORT_POWER feature. + * + * Return: 0 if successful. A negative error code otherwise. + */ +int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, +			   int port1, bool set) +{ +	int ret; + +	if (set) +		ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); +	else +		ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER); + +	if (ret) +		return ret; + +	if (set) +		set_bit(port1, hub->power_bits); +	else +		clear_bit(port1, hub->power_bits); +	return 0; +} + +/**   * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub   * @urb: an URB associated with the failed or incomplete split transaction   * @@ -507,6 +773,8 @@ static void hub_tt_work(struct work_struct *work)   *   * It may not be possible for that hub to handle additional full (or low)   * speed transactions until that state is fully cleared out. + * + * Return: 0 if successful. A negative error code otherwise.   */  int usb_hub_clear_tt_buffer(struct urb *urb)  { @@ -549,16 +817,9 @@ int usb_hub_clear_tt_buffer(struct urb *urb)  }  EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer); -/* If do_delay is false, return the number of milliseconds the caller - * needs to delay. - */ -static unsigned hub_power_on(struct usb_hub *hub, bool do_delay) +static void hub_power_on(struct usb_hub *hub, bool do_delay)  {  	int port1; -	unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; -	unsigned delay; -	u16 wHubCharacteristics = -			le16_to_cpu(hub->descriptor->wHubCharacteristics);  	/* Enable power on each port.  Some hubs have reserved values  	 * of LPSM (> 2) in their descriptors, even though they are @@ -566,19 +827,19 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)  	 * but only emulate it.  In all cases, the ports won't work  	 * unless we send these messages to the hub.  	 */ -	if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) +	if (hub_is_port_power_switchable(hub))  		dev_dbg(hub->intfdev, "enabling power on all ports\n");  	else  		dev_dbg(hub->intfdev, "trying to enable port power on "  				"non-switchable hub\n"); -	for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) -		set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); - -	/* Wait at least 100 msec for power to become stable */ -	delay = max(pgood_delay, (unsigned) 100); +	for (port1 = 1; port1 <= hub->hdev->maxchild; port1++) +		if (test_bit(port1, hub->power_bits)) +			set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); +		else +			usb_clear_port_feature(hub->hdev, port1, +						USB_PORT_FEAT_POWER);  	if (do_delay) -		msleep(delay); -	return delay; +		msleep(hub_power_on_good_delay(hub));  }  static int hub_hub_status(struct usb_hub *hub, @@ -588,42 +849,117 @@ static int hub_hub_status(struct usb_hub *hub,  	mutex_lock(&hub->status_mutex);  	ret = get_hub_status(hub->hdev, &hub->status->hub); -	if (ret < 0) -		dev_err (hub->intfdev, -			"%s failed (err = %d)\n", __func__, ret); -	else { +	if (ret < 0) { +		if (ret != -ENODEV) +			dev_err(hub->intfdev, +				"%s failed (err = %d)\n", __func__, ret); +	} else {  		*status = le16_to_cpu(hub->status->hub.wHubStatus); -		*change = le16_to_cpu(hub->status->hub.wHubChange);  +		*change = le16_to_cpu(hub->status->hub.wHubChange);  		ret = 0;  	}  	mutex_unlock(&hub->status_mutex);  	return ret;  } +static int hub_set_port_link_state(struct usb_hub *hub, int port1, +			unsigned int link_status) +{ +	return set_port_feature(hub->hdev, +			port1 | (link_status << 3), +			USB_PORT_FEAT_LINK_STATE); +} + +/* + * If USB 3.0 ports are placed into the Disabled state, they will no longer + * detect any device connects or disconnects.  This is generally not what the + * USB core wants, since it expects a disabled port to produce a port status + * change event when a new device connects. + * + * Instead, set the link state to Disabled, wait for the link to settle into + * that state, clear any change bits, and then put the port into the RxDetect + * state. + */ +static int hub_usb3_port_disable(struct usb_hub *hub, int port1) +{ +	int ret; +	int total_time; +	u16 portchange, portstatus; + +	if (!hub_is_superspeed(hub->hdev)) +		return -EINVAL; + +	ret = hub_port_status(hub, port1, &portstatus, &portchange); +	if (ret < 0) +		return ret; + +	/* +	 * USB controller Advanced Micro Devices, Inc. [AMD] FCH USB XHCI +	 * Controller [1022:7814] will have spurious result making the following +	 * usb 3.0 device hotplugging route to the 2.0 root hub and recognized +	 * as high-speed device if we set the usb 3.0 port link state to +	 * Disabled. Since it's already in USB_SS_PORT_LS_RX_DETECT state, we +	 * check the state here to avoid the bug. +	 */ +	if ((portstatus & USB_PORT_STAT_LINK_STATE) == +				USB_SS_PORT_LS_RX_DETECT) { +		dev_dbg(&hub->ports[port1 - 1]->dev, +			 "Not disabling port; link state is RxDetect\n"); +		return ret; +	} + +	ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED); +	if (ret) +		return ret; + +	/* Wait for the link to enter the disabled state. */ +	for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) { +		ret = hub_port_status(hub, port1, &portstatus, &portchange); +		if (ret < 0) +			return ret; + +		if ((portstatus & USB_PORT_STAT_LINK_STATE) == +				USB_SS_PORT_LS_SS_DISABLED) +			break; +		if (total_time >= HUB_DEBOUNCE_TIMEOUT) +			break; +		msleep(HUB_DEBOUNCE_STEP); +	} +	if (total_time >= HUB_DEBOUNCE_TIMEOUT) +		dev_warn(&hub->ports[port1 - 1]->dev, +				"Could not disable after %d ms\n", total_time); + +	return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT); +} +  static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)  { +	struct usb_port *port_dev = hub->ports[port1 - 1];  	struct usb_device *hdev = hub->hdev;  	int ret = 0; -	if (hdev->children[port1-1] && set_state) -		usb_set_device_state(hdev->children[port1-1], -				USB_STATE_NOTATTACHED); -	if (!hub->error) -		ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); -	if (ret) -		dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", -				port1, ret); +	if (port_dev->child && set_state) +		usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED); +	if (!hub->error) { +		if (hub_is_superspeed(hub->hdev)) +			ret = hub_usb3_port_disable(hub, port1); +		else +			ret = usb_clear_port_feature(hdev, port1, +					USB_PORT_FEAT_ENABLE); +	} +	if (ret && ret != -ENODEV) +		dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);  	return ret;  }  /* - * Disable a port and mark a logical connnect-change event, so that some + * Disable a port and mark a logical connect-change event, so that some   * time later khubd will disconnect() any existing usb_device on the port   * and will re-enumerate if there actually is a device attached.   */  static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)  { -	dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1); +	dev_dbg(&hub->ports[port1 - 1]->dev, "logical disconnect\n");  	hub_port_disable(hub, port1, 1);  	/* FIXME let caller ask to power down the port: @@ -636,7 +972,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)  	 */  	set_bit(port1, hub->change_bits); - 	kick_khubd(hub); +	kick_khubd(hub);  }  /** @@ -648,6 +984,8 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)   * see that the device has been disconnected.  When the device is   * physically unplugged and something is plugged in, the events will   * be received and processed normally. + * + * Return: 0 if successful. A negative error code otherwise.   */  int usb_remove_device(struct usb_device *udev)  { @@ -656,7 +994,7 @@ int usb_remove_device(struct usb_device *udev)  	if (!udev->parent)	/* Can't remove a root hub */  		return -EINVAL; -	hub = hdev_to_hub(udev->parent); +	hub = usb_hub_to_struct_hub(udev->parent);  	intf = to_usb_interface(hub->intfdev);  	usb_autopm_get_interface(intf); @@ -677,6 +1015,8 @@ static void hub_init_func3(struct work_struct *ws);  static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  {  	struct usb_device *hdev = hub->hdev; +	struct usb_hcd *hcd; +	int ret;  	int port1;  	int status;  	bool need_debounce_delay = false; @@ -688,10 +1028,26 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  	if (type == HUB_INIT3)  		goto init3; -	/* After a resume, port power should still be on. +	/* The superspeed hub except for root hub has to use Hub Depth +	 * value as an offset into the route string to locate the bits +	 * it uses to determine the downstream port number. So hub driver +	 * should send a set hub depth request to superspeed hub after +	 * the superspeed hub is set configuration in initialization or +	 * reset procedure. +	 * +	 * After a resume, port power should still be on.  	 * For any other type of activation, turn it on.  	 */  	if (type != HUB_RESUME) { +		if (hdev->parent && hub_is_superspeed(hdev)) { +			ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), +					HUB_SET_DEPTH, USB_RT_HUB, +					hdev->level - 1, 0, NULL, 0, +					USB_CTRL_SET_TIMEOUT); +			if (ret < 0) +				dev_err(hub->intfdev, +						"set hub depth failed\n"); +		}  		/* Speed up system boot by using a delayed_work for the  		 * hub's initial power-up delays.  This is pretty awkward @@ -706,36 +1062,60 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  		 * for HUB_POST_RESET, but it's easier not to.  		 */  		if (type == HUB_INIT) { -			delay = hub_power_on(hub, false); -			PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2); -			schedule_delayed_work(&hub->init_work, +			unsigned delay = hub_power_on_good_delay(hub); + +			hub_power_on(hub, false); +			INIT_DELAYED_WORK(&hub->init_work, hub_init_func2); +			queue_delayed_work(system_power_efficient_wq, +					&hub->init_work,  					msecs_to_jiffies(delay));  			/* Suppress autosuspend until init is done */  			usb_autopm_get_interface_no_resume(  					to_usb_interface(hub->intfdev));  			return;		/* Continues at init2: below */ +		} else if (type == HUB_RESET_RESUME) { +			/* The internal host controller state for the hub device +			 * may be gone after a host power loss on system resume. +			 * Update the device's info so the HW knows it's a hub. +			 */ +			hcd = bus_to_hcd(hdev->bus); +			if (hcd->driver->update_hub_device) { +				ret = hcd->driver->update_hub_device(hcd, hdev, +						&hub->tt, GFP_NOIO); +				if (ret < 0) { +					dev_err(hub->intfdev, "Host not " +							"accepting hub info " +							"update.\n"); +					dev_err(hub->intfdev, "LS/FS devices " +							"and hubs may not work " +							"under this hub\n."); +				} +			} +			hub_power_on(hub, true);  		} else {  			hub_power_on(hub, true);  		}  	}   init2: -	/* Check each port and set hub->change_bits to let khubd know +	/* +	 * Check each port and set hub->change_bits to let khubd know  	 * which ports need attention.  	 */  	for (port1 = 1; port1 <= hdev->maxchild; ++port1) { -		struct usb_device *udev = hdev->children[port1-1]; +		struct usb_port *port_dev = hub->ports[port1 - 1]; +		struct usb_device *udev = port_dev->child;  		u16 portstatus, portchange;  		portstatus = portchange = 0;  		status = hub_port_status(hub, port1, &portstatus, &portchange);  		if (udev || (portstatus & USB_PORT_STAT_CONNECTION)) -			dev_dbg(hub->intfdev, -					"port %d: status %04x change %04x\n", -					port1, portstatus, portchange); +			dev_dbg(&port_dev->dev, "status %04x change %04x\n", +					portstatus, portchange); -		/* After anything other than HUB_RESUME (i.e., initialization +		/* +		 * After anything other than HUB_RESUME (i.e., initialization  		 * or any sort of reset), every port should be disabled.  		 * Unconnected ports should likewise be disabled (paranoia),  		 * and so should ports for which we have no usb_device. @@ -748,34 +1128,37 @@ 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. +			 * Do not disable USB3 protocol ports, just pretend +			 * power was lost  			 */ -			if (hdev->descriptor.bDeviceProtocol != 3 || -			    (!hdev->parent && -			     !(portstatus & USB_PORT_STAT_SUPER_SPEED))) { -				clear_port_feature(hdev, port1, +			portstatus &= ~USB_PORT_STAT_ENABLE; +			if (!hub_is_superspeed(hdev)) +				usb_clear_port_feature(hdev, port1,  						   USB_PORT_FEAT_ENABLE); -				portstatus &= ~USB_PORT_STAT_ENABLE; -			} else { -				/* Pretend that power was lost for USB3 devs */ -				portstatus &= ~USB_PORT_STAT_ENABLE; -			}  		}  		/* Clear status-change flags; we'll debounce later */  		if (portchange & USB_PORT_STAT_C_CONNECTION) {  			need_debounce_delay = true; -			clear_port_feature(hub->hdev, port1, +			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_CONNECTION);  		}  		if (portchange & USB_PORT_STAT_C_ENABLE) {  			need_debounce_delay = true; -			clear_port_feature(hub->hdev, port1, +			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_ENABLE);  		} - +		if (portchange & USB_PORT_STAT_C_RESET) { +			need_debounce_delay = true; +			usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_RESET); +		} +		if ((portchange & USB_PORT_STAT_C_BH_RESET) && +				hub_is_superspeed(hub->hdev)) { +			need_debounce_delay = true; +			usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_BH_PORT_RESET); +		}  		/* We can forget about a "removed" device when there's a  		 * physical disconnect or the connect status changes.  		 */ @@ -787,23 +1170,35 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  			/* Tell khubd to disconnect the device or  			 * check for a new connection  			 */ -			if (udev || (portstatus & USB_PORT_STAT_CONNECTION)) +			if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || +			    (portstatus & USB_PORT_STAT_OVERCURRENT))  				set_bit(port1, hub->change_bits);  		} else if (portstatus & USB_PORT_STAT_ENABLE) { +			bool port_resumed = (portstatus & +					USB_PORT_STAT_LINK_STATE) == +				USB_SS_PORT_LS_U0;  			/* The power session apparently survived the resume.  			 * If there was an overcurrent or suspend change  			 * (i.e., remote wakeup request), have khubd -			 * take care of it. +			 * take care of it.  Look at the port link state +			 * for USB 3.0 hubs, since they don't have a suspend +			 * change bit, and they don't set the port link change +			 * bit on device-initiated resume.  			 */ -			if (portchange) +			if (portchange || (hub_is_superspeed(hub->hdev) && +						port_resumed))  				set_bit(port1, hub->change_bits);  		} else if (udev->persist_enabled) {  #ifdef CONFIG_PM  			udev->reset_resume = 1;  #endif -			set_bit(port1, hub->change_bits); +			/* Don't set the change_bits when the device +			 * was powered off. +			 */ +			if (test_bit(port1, hub->power_bits)) +				set_bit(port1, hub->change_bits);  		} else {  			/* The power session is gone; tell khubd */ @@ -825,8 +1220,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  		/* Don't do a long sleep inside a workqueue routine */  		if (type == HUB_INIT2) { -			PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); -			schedule_delayed_work(&hub->init_work, +			INIT_DELAYED_WORK(&hub->init_work, hub_init_func3); +			queue_delayed_work(system_power_efficient_wq, +					&hub->init_work,  					msecs_to_jiffies(delay));  			return;		/* Continues at init3: below */  		} else { @@ -840,7 +1236,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  	if (status < 0)  		dev_err(hub->intfdev, "activate --> %d\n", status);  	if (hub->has_indicators && blinkenlights) -		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); +		queue_delayed_work(system_power_efficient_wq, +				&hub->leds, LED_CYCLE_PERIOD);  	/* Scan all ports that need attention */  	kick_khubd(hub); @@ -882,8 +1279,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)  	if (type != HUB_SUSPEND) {  		/* Disconnect all the children */  		for (i = 0; i < hdev->maxchild; ++i) { -			if (hdev->children[i]) -				usb_disconnect(&hdev->children[i]); +			if (hub->ports[i]->child) +				usb_disconnect(&hub->ports[i]->child);  		}  	} @@ -892,7 +1289,15 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)  	if (hub->has_indicators)  		cancel_delayed_work_sync(&hub->leds);  	if (hub->tt.hub) -		cancel_work_sync(&hub->tt.clear_work); +		flush_work(&hub->tt.clear_work); +} + +static void hub_pm_barrier_for_all_ports(struct usb_hub *hub) +{ +	int i; + +	for (i = 0; i < hub->hdev->maxchild; ++i) +		pm_runtime_barrier(&hub->ports[i]->dev);  }  /* caller has locked the hub device */ @@ -901,6 +1306,8 @@ static int hub_pre_reset(struct usb_interface *intf)  	struct usb_hub *hub = usb_get_intfdata(intf);  	hub_quiesce(hub, HUB_PRE_RESET); +	hub->in_reset = 1; +	hub_pm_barrier_for_all_ports(hub);  	return 0;  } @@ -909,6 +1316,8 @@ static int hub_post_reset(struct usb_interface *intf)  {  	struct usb_hub *hub = usb_get_intfdata(intf); +	hub->in_reset = 0; +	hub_pm_barrier_for_all_ports(hub);  	hub_activate(hub, HUB_POST_RESET);  	return 0;  } @@ -922,8 +1331,11 @@ static int hub_configure(struct usb_hub *hub,  	u16 hubstatus, hubchange;  	u16 wHubCharacteristics;  	unsigned int pipe; -	int maxp, ret; +	int maxp, ret, i;  	char *message = "out of memory"; +	unsigned unit_load; +	unsigned full_load; +	unsigned maxchild;  	hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);  	if (!hub->buffer) { @@ -948,8 +1360,7 @@ static int hub_configure(struct usb_hub *hub,  	 * hub->descriptor can handle USB_MAXCHILDREN ports,  	 * but the hub can/will return fewer bytes here.  	 */ -	ret = get_hub_descriptor(hdev, hub->descriptor, -			sizeof(*hub->descriptor)); +	ret = get_hub_descriptor(hdev, hub->descriptor);  	if (ret < 0) {  		message = "can't read hub descriptor";  		goto fail; @@ -957,116 +1368,129 @@ static int hub_configure(struct usb_hub *hub,  		message = "hub has too many ports!";  		ret = -ENODEV;  		goto fail; +	} else if (hub->descriptor->bNbrPorts == 0) { +		message = "hub doesn't have any ports!"; +		ret = -ENODEV; +		goto fail;  	} -	hdev->maxchild = hub->descriptor->bNbrPorts; -	dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, -		(hdev->maxchild == 1) ? "" : "s"); +	maxchild = hub->descriptor->bNbrPorts; +	dev_info(hub_dev, "%d port%s detected\n", maxchild, +			(maxchild == 1) ? "" : "s"); -	hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL); -	if (!hub->port_owners) { +	hub->ports = kzalloc(maxchild * sizeof(struct usb_port *), GFP_KERNEL); +	if (!hub->ports) {  		ret = -ENOMEM;  		goto fail;  	}  	wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); +	if (hub_is_superspeed(hdev)) { +		unit_load = 150; +		full_load = 900; +	} else { +		unit_load = 100; +		full_load = 500; +	} -	if (wHubCharacteristics & HUB_CHAR_COMPOUND) { +	/* FIXME for USB 3.0, skip for now */ +	if ((wHubCharacteristics & HUB_CHAR_COMPOUND) && +			!(hub_is_superspeed(hdev))) {  		int	i; -		char	portstr [USB_MAXCHILDREN + 1]; +		char	portstr[USB_MAXCHILDREN + 1]; -		for (i = 0; i < hdev->maxchild; i++) -			portstr[i] = hub->descriptor->DeviceRemovable +		for (i = 0; i < maxchild; i++) +			portstr[i] = hub->descriptor->u.hs.DeviceRemovable  				    [((i + 1) / 8)] & (1 << ((i + 1) % 8))  				? 'F' : 'R'; -		portstr[hdev->maxchild] = 0; +		portstr[maxchild] = 0;  		dev_dbg(hub_dev, "compound device; port removable status: %s\n", portstr);  	} else  		dev_dbg(hub_dev, "standalone hub\n");  	switch (wHubCharacteristics & HUB_CHAR_LPSM) { -		case 0x00: -			dev_dbg(hub_dev, "ganged power switching\n"); -			break; -		case 0x01: -			dev_dbg(hub_dev, "individual port power switching\n"); -			break; -		case 0x02: -		case 0x03: -			dev_dbg(hub_dev, "no power switching (usb 1.0)\n"); -			break; +	case HUB_CHAR_COMMON_LPSM: +		dev_dbg(hub_dev, "ganged power switching\n"); +		break; +	case HUB_CHAR_INDV_PORT_LPSM: +		dev_dbg(hub_dev, "individual port power switching\n"); +		break; +	case HUB_CHAR_NO_LPSM: +	case HUB_CHAR_LPSM: +		dev_dbg(hub_dev, "no power switching (usb 1.0)\n"); +		break;  	}  	switch (wHubCharacteristics & HUB_CHAR_OCPM) { -		case 0x00: -			dev_dbg(hub_dev, "global over-current protection\n"); -			break; -		case 0x08: -			dev_dbg(hub_dev, "individual port over-current protection\n"); -			break; -		case 0x10: -		case 0x18: -			dev_dbg(hub_dev, "no over-current protection\n"); -                        break; +	case HUB_CHAR_COMMON_OCPM: +		dev_dbg(hub_dev, "global over-current protection\n"); +		break; +	case HUB_CHAR_INDV_PORT_OCPM: +		dev_dbg(hub_dev, "individual port over-current protection\n"); +		break; +	case HUB_CHAR_NO_OCPM: +	case HUB_CHAR_OCPM: +		dev_dbg(hub_dev, "no over-current protection\n"); +		break;  	}  	spin_lock_init (&hub->tt.lock);  	INIT_LIST_HEAD (&hub->tt.clear_list);  	INIT_WORK(&hub->tt.clear_work, hub_tt_work);  	switch (hdev->descriptor.bDeviceProtocol) { -		case 0: -			break; -		case 1: -			dev_dbg(hub_dev, "Single TT\n"); -			hub->tt.hub = hdev; -			break; -		case 2: -			ret = usb_set_interface(hdev, 0, 1); -			if (ret == 0) { -				dev_dbg(hub_dev, "TT per port\n"); -				hub->tt.multi = 1; -			} else -				dev_err(hub_dev, "Using single TT (err %d)\n", -					ret); -			hub->tt.hub = hdev; -			break; -		case 3: -			/* USB 3.0 hubs don't have a TT */ -			break; -		default: -			dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", -				hdev->descriptor.bDeviceProtocol); -			break; +	case USB_HUB_PR_FS: +		break; +	case USB_HUB_PR_HS_SINGLE_TT: +		dev_dbg(hub_dev, "Single TT\n"); +		hub->tt.hub = hdev; +		break; +	case USB_HUB_PR_HS_MULTI_TT: +		ret = usb_set_interface(hdev, 0, 1); +		if (ret == 0) { +			dev_dbg(hub_dev, "TT per port\n"); +			hub->tt.multi = 1; +		} else +			dev_err(hub_dev, "Using single TT (err %d)\n", +				ret); +		hub->tt.hub = hdev; +		break; +	case USB_HUB_PR_SS: +		/* USB 3.0 hubs don't have a TT */ +		break; +	default: +		dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", +			hdev->descriptor.bDeviceProtocol); +		break;  	}  	/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */  	switch (wHubCharacteristics & HUB_CHAR_TTTT) { -		case HUB_TTTT_8_BITS: -			if (hdev->descriptor.bDeviceProtocol != 0) { -				hub->tt.think_time = 666; -				dev_dbg(hub_dev, "TT requires at most %d " -						"FS bit times (%d ns)\n", -					8, hub->tt.think_time); -			} -			break; -		case HUB_TTTT_16_BITS: -			hub->tt.think_time = 666 * 2; +	case HUB_TTTT_8_BITS: +		if (hdev->descriptor.bDeviceProtocol != 0) { +			hub->tt.think_time = 666;  			dev_dbg(hub_dev, "TT requires at most %d "  					"FS bit times (%d ns)\n", -				16, hub->tt.think_time); -			break; -		case HUB_TTTT_24_BITS: -			hub->tt.think_time = 666 * 3; -			dev_dbg(hub_dev, "TT requires at most %d " -					"FS bit times (%d ns)\n", -				24, hub->tt.think_time); -			break; -		case HUB_TTTT_32_BITS: -			hub->tt.think_time = 666 * 4; -			dev_dbg(hub_dev, "TT requires at most %d " -					"FS bit times (%d ns)\n", -				32, hub->tt.think_time); -			break; +				8, hub->tt.think_time); +		} +		break; +	case HUB_TTTT_16_BITS: +		hub->tt.think_time = 666 * 2; +		dev_dbg(hub_dev, "TT requires at most %d " +				"FS bit times (%d ns)\n", +			16, hub->tt.think_time); +		break; +	case HUB_TTTT_24_BITS: +		hub->tt.think_time = 666 * 3; +		dev_dbg(hub_dev, "TT requires at most %d " +				"FS bit times (%d ns)\n", +			24, hub->tt.think_time); +		break; +	case HUB_TTTT_32_BITS: +		hub->tt.think_time = 666 * 4; +		dev_dbg(hub_dev, "TT requires at most %d " +				"FS bit times (%d ns)\n", +			32, hub->tt.think_time); +		break;  	}  	/* probe() zeroes hub->indicator[] */ @@ -1082,54 +1506,45 @@ static int hub_configure(struct usb_hub *hub,  	 * and battery-powered root hubs (may provide just 8 mA).  	 */  	ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); -	if (ret < 2) { +	if (ret) {  		message = "can't get hub status";  		goto fail;  	} -	le16_to_cpus(&hubstatus); +	hcd = bus_to_hcd(hdev->bus);  	if (hdev == hdev->bus->root_hub) { -		if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) -			hub->mA_per_port = 500; +		if (hcd->power_budget > 0) +			hdev->bus_mA = hcd->power_budget; +		else +			hdev->bus_mA = full_load * maxchild; +		if (hdev->bus_mA >= full_load) +			hub->mA_per_port = full_load;  		else {  			hub->mA_per_port = hdev->bus_mA;  			hub->limited_power = 1;  		}  	} else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { +		int remaining = hdev->bus_mA - +			hub->descriptor->bHubContrCurrent; +  		dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",  			hub->descriptor->bHubContrCurrent);  		hub->limited_power = 1; -		if (hdev->maxchild > 0) { -			int remaining = hdev->bus_mA - -					hub->descriptor->bHubContrCurrent; -			if (remaining < hdev->maxchild * 100) -				dev_warn(hub_dev, +		if (remaining < maxchild * unit_load) +			dev_warn(hub_dev,  					"insufficient power available "  					"to use all downstream ports\n"); -			hub->mA_per_port = 100;		/* 7.2.1.1 */ -		} +		hub->mA_per_port = unit_load;	/* 7.2.1 */ +  	} else {	/* Self-powered external hub */  		/* FIXME: What about battery-powered external hubs that  		 * provide less current per port? */ -		hub->mA_per_port = 500; +		hub->mA_per_port = full_load;  	} -	if (hub->mA_per_port < 500) +	if (hub->mA_per_port < full_load)  		dev_dbg(hub_dev, "%umA bus power budget for each child\n",  				hub->mA_per_port); -	/* Update the HCD's internal representation of this hub before khubd -	 * starts getting port status changes for devices under the hub. -	 */ -	hcd = bus_to_hcd(hdev->bus); -	if (hcd->driver->update_hub_device) { -		ret = hcd->driver->update_hub_device(hcd, hdev, -				&hub->tt, GFP_KERNEL); -		if (ret < 0) { -			message = "can't update HCD hub info"; -			goto fail; -		} -	} -  	ret = hub_hub_status(hub, &hubstatus, &hubchange);  	if (ret < 0) {  		message = "can't get hub status"; @@ -1169,7 +1584,41 @@ static int hub_configure(struct usb_hub *hub,  	/* maybe cycle the hub leds */  	if (hub->has_indicators && blinkenlights) -		hub->indicator [0] = INDICATOR_CYCLE; +		hub->indicator[0] = INDICATOR_CYCLE; + +	mutex_lock(&usb_port_peer_mutex); +	for (i = 0; i < maxchild; i++) { +		ret = usb_hub_create_port_device(hub, i + 1); +		if (ret < 0) { +			dev_err(hub->intfdev, +				"couldn't create port%d device.\n", i + 1); +			break; +		} +	} +	hdev->maxchild = i; +	for (i = 0; i < hdev->maxchild; i++) { +		struct usb_port *port_dev = hub->ports[i]; + +		pm_runtime_put(&port_dev->dev); +	} + +	mutex_unlock(&usb_port_peer_mutex); +	if (ret < 0) +		goto fail; + +	/* Update the HCD's internal representation of this hub before khubd +	 * starts getting port status changes for devices under the hub. +	 */ +	if (hcd->driver->update_hub_device) { +		ret = hcd->driver->update_hub_device(hcd, hdev, +				&hub->tt, GFP_KERNEL); +		if (ret < 0) { +			message = "can't update HCD hub info"; +			goto fail; +		} +	} + +	usb_hub_adjust_deviceremovable(hdev, hub->descriptor);  	hub_activate(hub, HUB_INIT);  	return 0; @@ -1193,7 +1642,9 @@ static unsigned highspeed_hubs;  static void hub_disconnect(struct usb_interface *intf)  { -	struct usb_hub *hub = usb_get_intfdata (intf); +	struct usb_hub *hub = usb_get_intfdata(intf); +	struct usb_device *hdev = interface_to_usbdev(intf); +	int port1;  	/* Take the hub off the event list and don't let it be added again */  	spin_lock_irq(&hub_event_lock); @@ -1208,18 +1659,30 @@ static void hub_disconnect(struct usb_interface *intf)  	hub->error = 0;  	hub_quiesce(hub, HUB_DISCONNECT); -	usb_set_intfdata (intf, NULL); -	hub->hdev->maxchild = 0; +	mutex_lock(&usb_port_peer_mutex); + +	/* Avoid races with recursively_mark_NOTATTACHED() */ +	spin_lock_irq(&device_state_lock); +	port1 = hdev->maxchild; +	hdev->maxchild = 0; +	usb_set_intfdata(intf, NULL); +	spin_unlock_irq(&device_state_lock); + +	for (; port1 > 0; --port1) +		usb_hub_remove_port_device(hub, port1); + +	mutex_unlock(&usb_port_peer_mutex);  	if (hub->hdev->speed == USB_SPEED_HIGH)  		highspeed_hubs--;  	usb_free_urb(hub->urb); -	kfree(hub->port_owners); +	kfree(hub->ports);  	kfree(hub->descriptor);  	kfree(hub->status);  	kfree(hub->buffer); +	pm_suspend_ignore_children(&intf->dev, false);  	kref_put(&hub->kref, hub_release);  } @@ -1233,8 +1696,54 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)  	desc = intf->cur_altsetting;  	hdev = interface_to_usbdev(intf); -	/* Hubs have proper suspend/resume support */ -	usb_enable_autosuspend(hdev); +	/* +	 * Set default autosuspend delay as 0 to speedup bus suspend, +	 * based on the below considerations: +	 * +	 * - Unlike other drivers, the hub driver does not rely on the +	 *   autosuspend delay to provide enough time to handle a wakeup +	 *   event, and the submitted status URB is just to check future +	 *   change on hub downstream ports, so it is safe to do it. +	 * +	 * - The patch might cause one or more auto supend/resume for +	 *   below very rare devices when they are plugged into hub +	 *   first time: +	 * +	 *   	devices having trouble initializing, and disconnect +	 *   	themselves from the bus and then reconnect a second +	 *   	or so later +	 * +	 *   	devices just for downloading firmware, and disconnects +	 *   	themselves after completing it +	 * +	 *   For these quite rare devices, their drivers may change the +	 *   autosuspend delay of their parent hub in the probe() to one +	 *   appropriate value to avoid the subtle problem if someone +	 *   does care it. +	 * +	 * - The patch may cause one or more auto suspend/resume on +	 *   hub during running 'lsusb', but it is probably too +	 *   infrequent to worry about. +	 * +	 * - Change autosuspend delay of hub can avoid unnecessary auto +	 *   suspend timer for hub, also may decrease power consumption +	 *   of USB bus. +	 */ +	pm_runtime_set_autosuspend_delay(&hdev->dev, 0); + +	/* +	 * Hubs have proper suspend/resume support, except for root hubs +	 * where the controller driver doesn't have bus_suspend and +	 * bus_resume methods. +	 */ +	if (hdev->parent) {		/* normal device */ +		usb_enable_autosuspend(hdev); +	} else {			/* root hub */ +		const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver; + +		if (drv->bus_suspend && drv->bus_resume) +			usb_enable_autosuspend(hdev); +	}  	if (hdev->level == MAX_TOPO_LEVEL) {  		dev_err(&intf->dev, @@ -1287,10 +1796,14 @@ descriptor_error:  	usb_set_intfdata (intf, hub);  	intf->needs_remote_wakeup = 1; +	pm_suspend_ignore_children(&intf->dev, true);  	if (hdev->speed == USB_SPEED_HIGH)  		highspeed_hubs++; +	if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) +		hub->quirk_check_port_auto_suspend = 1; +  	if (hub_configure(hub, endpoint) >= 0)  		return 0; @@ -1298,11 +1811,11 @@ descriptor_error:  	return -ENODEV;  } -/* No BKL needed */  static int  hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)  {  	struct usb_device *hdev = interface_to_usbdev (intf); +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);  	/* assert ifno == 0 (part of hub spec) */  	switch (code) { @@ -1316,11 +1829,11 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)  		else {  			info->nports = hdev->maxchild;  			for (i = 0; i < info->nports; i++) { -				if (hdev->children[i] == NULL) +				if (hub->ports[i]->child == NULL)  					info->port[i] = 0;  				else  					info->port[i] = -						hdev->children[i]->devnum; +						hub->ports[i]->child->devnum;  			}  		}  		spin_unlock_irq(&device_state_lock); @@ -1338,25 +1851,28 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)   * to one of these "claimed" ports, the program will "own" the device.   */  static int find_port_owner(struct usb_device *hdev, unsigned port1, -		void ***ppowner) +		struct usb_dev_state ***ppowner)  { +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); +  	if (hdev->state == USB_STATE_NOTATTACHED)  		return -ENODEV;  	if (port1 == 0 || port1 > hdev->maxchild)  		return -EINVAL; -	/* This assumes that devices not managed by the hub driver +	/* Devices not managed by the hub driver  	 * will always have maxchild equal to 0.  	 */ -	*ppowner = &(hdev_to_hub(hdev)->port_owners[port1 - 1]); +	*ppowner = &(hub->ports[port1 - 1]->port_owner);  	return 0;  }  /* In the following three functions, the caller must hold hdev's lock */ -int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner) +int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, +		       struct usb_dev_state *owner)  {  	int rc; -	void **powner; +	struct usb_dev_state **powner;  	rc = find_port_owner(hdev, port1, &powner);  	if (rc) @@ -1366,11 +1882,13 @@ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner)  	*powner = owner;  	return rc;  } +EXPORT_SYMBOL_GPL(usb_hub_claim_port); -int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner) +int usb_hub_release_port(struct usb_device *hdev, unsigned port1, +			 struct usb_dev_state *owner)  {  	int rc; -	void **powner; +	struct usb_dev_state **powner;  	rc = find_port_owner(hdev, port1, &powner);  	if (rc) @@ -1380,19 +1898,18 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner)  	*powner = NULL;  	return rc;  } +EXPORT_SYMBOL_GPL(usb_hub_release_port); -void usb_hub_release_all_ports(struct usb_device *hdev, void *owner) +void usb_hub_release_all_ports(struct usb_device *hdev, struct usb_dev_state *owner)  { +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);  	int n; -	void **powner; -	n = find_port_owner(hdev, 1, &powner); -	if (n == 0) { -		for (; n < hdev->maxchild; (++n, ++powner)) { -			if (*powner == owner) -				*powner = NULL; -		} +	for (n = 0; n < hdev->maxchild; n++) { +		if (hub->ports[n]->port_owner == owner) +			hub->ports[n]->port_owner = NULL;  	} +  }  /* The caller must hold udev's lock */ @@ -1402,18 +1919,18 @@ bool usb_device_is_owned(struct usb_device *udev)  	if (udev->state == USB_STATE_NOTATTACHED || !udev->parent)  		return false; -	hub = hdev_to_hub(udev->parent); -	return !!hub->port_owners[udev->portnum - 1]; +	hub = usb_hub_to_struct_hub(udev->parent); +	return !!hub->ports[udev->portnum - 1]->port_owner;  } -  static void recursively_mark_NOTATTACHED(struct usb_device *udev)  { +	struct usb_hub *hub = usb_hub_to_struct_hub(udev);  	int i;  	for (i = 0; i < udev->maxchild; ++i) { -		if (udev->children[i]) -			recursively_mark_NOTATTACHED(udev->children[i]); +		if (hub->ports[i]->child) +			recursively_mark_NOTATTACHED(hub->ports[i]->child);  	}  	if (udev->state == USB_STATE_SUSPENDED)  		udev->active_duration -= jiffies; @@ -1445,6 +1962,7 @@ void usb_set_device_state(struct usb_device *udev,  		enum usb_device_state new_state)  {  	unsigned long flags; +	int wakeup = -1;  	spin_lock_irqsave(&device_state_lock, flags);  	if (udev->state == USB_STATE_NOTATTACHED) @@ -1459,11 +1977,10 @@ void usb_set_device_state(struct usb_device *udev,  					|| new_state == USB_STATE_SUSPENDED)  				;	/* No change to wakeup settings */  			else if (new_state == USB_STATE_CONFIGURED) -				device_set_wakeup_capable(&udev->dev, -					(udev->actconfig->desc.bmAttributes -					 & USB_CONFIG_ATT_WAKEUP)); +				wakeup = udev->actconfig->desc.bmAttributes +					 & USB_CONFIG_ATT_WAKEUP;  			else -				device_set_wakeup_capable(&udev->dev, 0); +				wakeup = 0;  		}  		if (udev->state == USB_STATE_SUSPENDED &&  			new_state != USB_STATE_SUSPENDED) @@ -1475,10 +1992,19 @@ void usb_set_device_state(struct usb_device *udev,  	} else  		recursively_mark_NOTATTACHED(udev);  	spin_unlock_irqrestore(&device_state_lock, flags); +	if (wakeup >= 0) +		device_set_wakeup_capable(&udev->dev, wakeup);  }  EXPORT_SYMBOL_GPL(usb_set_device_state);  /* + * Choose a device number. + * + * Device numbers are used as filenames in usbfs.  On USB-1.1 and + * USB-2.0 buses they are also used as device addresses, however on + * USB-3.0 buses the address is assigned by the controller hardware + * and it usually is not the same as the device number. + *   * WUSB devices are simple: they have no hubs behind, so the mapping   * device <-> virtual port number becomes 1:1. Why? to simplify the   * life of the device connection logic in @@ -1500,7 +2026,7 @@ EXPORT_SYMBOL_GPL(usb_set_device_state);   * the HCD must setup data structures before issuing a set address   * command to the hardware.   */ -static void choose_address(struct usb_device *udev) +static void choose_devnum(struct usb_device *udev)  {  	int		devnum;  	struct usb_bus	*bus = udev->bus; @@ -1517,7 +2043,7 @@ static void choose_address(struct usb_device *udev)  		if (devnum >= 128)  			devnum = find_next_zero_bit(bus->devmap.devicemap,  						    128, 1); -		bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); +		bus->devnum_next = (devnum >= 127 ? 1 : devnum + 1);  	}  	if (devnum < 128) {  		set_bit(devnum, bus->devmap.devicemap); @@ -1525,7 +2051,7 @@ static void choose_address(struct usb_device *udev)  	}  } -static void release_address(struct usb_device *udev) +static void release_devnum(struct usb_device *udev)  {  	if (udev->devnum > 0) {  		clear_bit(udev->devnum, udev->bus->devmap.devicemap); @@ -1533,7 +2059,7 @@ static void release_address(struct usb_device *udev)  	}  } -static void update_address(struct usb_device *udev, int devnum) +static void update_devnum(struct usb_device *udev, int devnum)  {  	/* The address for a WUSB device is managed by wusbcore. */  	if (!udev->wusb) @@ -1549,6 +2075,18 @@ static void hub_free_dev(struct usb_device *udev)  		hcd->driver->free_dev(hcd, udev);  } +static void hub_disconnect_children(struct usb_device *udev) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(udev); +	int i; + +	/* Free up all the children before we remove this device */ +	for (i = 0; i < udev->maxchild; i++) { +		if (hub->ports[i]->child) +			usb_disconnect(&hub->ports[i]->child); +	} +} +  /**   * usb_disconnect - disconnect a device (usbcore-internal)   * @pdev: pointer to device being disconnected @@ -1557,8 +2095,8 @@ static void hub_free_dev(struct usb_device *udev)   * Something got disconnected. Get rid of it and all of its children.   *   * If *pdev is a normal device then the parent hub must already be locked. - * If *pdev is a root hub then this routine will acquire the - * usb_bus_list_lock on behalf of the caller. + * If *pdev is a root hub then the caller must hold the usb_bus_list_lock, + * which protects the set of root hubs as well as the list of buses.   *   * Only hub drivers (including virtual root hub drivers for host   * controllers) should ever call this. @@ -1567,28 +2105,22 @@ static void hub_free_dev(struct usb_device *udev)   */  void usb_disconnect(struct usb_device **pdev)  { -	struct usb_device	*udev = *pdev; -	int			i; - -	if (!udev) { -		pr_debug ("%s nodev\n", __func__); -		return; -	} +	struct usb_port *port_dev = NULL; +	struct usb_device *udev = *pdev; +	struct usb_hub *hub; +	int port1;  	/* mark the device as inactive, so any further urb submissions for  	 * this device (and any of its children) will fail immediately. -	 * this quiesces everyting except pending urbs. +	 * this quiesces everything except pending urbs.  	 */  	usb_set_device_state(udev, USB_STATE_NOTATTACHED); -	dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); +	dev_info(&udev->dev, "USB disconnect, device number %d\n", +			udev->devnum);  	usb_lock_device(udev); -	/* Free up all the children before we remove this device */ -	for (i = 0; i < USB_MAXCHILDREN; i++) { -		if (udev->children[i]) -			usb_disconnect(&udev->children[i]); -	} +	hub_disconnect_children(udev);  	/* deallocate hcd/hardware state ... nuking all pending urbs and  	 * cleaning up all state associated with the current configuration @@ -1598,6 +2130,22 @@ void usb_disconnect(struct usb_device **pdev)  	usb_disable_device(udev, 0);  	usb_hcd_synchronize_unlinks(udev); +	if (udev->parent) { +		port1 = udev->portnum; +		hub = usb_hub_to_struct_hub(udev->parent); +		port_dev = hub->ports[port1 - 1]; + +		sysfs_remove_link(&udev->dev.kobj, "port"); +		sysfs_remove_link(&port_dev->dev.kobj, "device"); + +		/* +		 * As usb_port_runtime_resume() de-references udev, make +		 * sure no resumes occur during removal +		 */ +		if (!test_and_set_bit(port1, hub->child_usage_bits)) +			pm_runtime_get_sync(&port_dev->dev); +	} +  	usb_remove_ep_devs(&udev->ep0);  	usb_unlock_device(udev); @@ -1610,13 +2158,16 @@ void usb_disconnect(struct usb_device **pdev)  	/* Free the device number and delete the parent's children[]  	 * (or root_hub) pointer.  	 */ -	release_address(udev); +	release_devnum(udev);  	/* Avoid races with recursively_mark_NOTATTACHED() */  	spin_lock_irq(&device_state_lock);  	*pdev = NULL;  	spin_unlock_irq(&device_state_lock); +	if (port_dev && test_and_clear_bit(port1, hub->child_usage_bits)) +		pm_runtime_put(&port_dev->dev); +  	hub_free_dev(udev);  	put_device(&udev->dev); @@ -1627,7 +2178,7 @@ static void show_string(struct usb_device *udev, char *id, char *string)  {  	if (!string)  		return; -	dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string); +	dev_info(&udev->dev, "%s: %s\n", id, string);  }  static void announce_device(struct usb_device *udev) @@ -1657,6 +2208,8 @@ static inline void announce_device(struct usb_device *udev) { }   * @udev: newly addressed device (in ADDRESS state)   *   * Finish enumeration for On-The-Go devices + * + * Return: 0 if successful. A negative error code otherwise.   */  static int usb_enumerate_device_otg(struct usb_device *udev)  { @@ -1739,6 +2292,8 @@ fail:   * If the device is WUSB and not authorized, we don't attempt to read   * the string descriptors, as they will be errored out by the device   * until it has been authorized. + * + * Return: 0 if successful. A negative error code otherwise.   */  static int usb_enumerate_device(struct usb_device *udev)  { @@ -1747,28 +2302,76 @@ static int usb_enumerate_device(struct usb_device *udev)  	if (udev->config == NULL) {  		err = usb_get_configuration(udev);  		if (err < 0) { -			dev_err(&udev->dev, "can't read configurations, error %d\n", -				err); -			goto fail; +			if (err != -ENODEV) +				dev_err(&udev->dev, "can't read configurations, error %d\n", +						err); +			return err;  		}  	} -	if (udev->wusb == 1 && udev->authorized == 0) { -		udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); -		udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); -		udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); -	} -	else { -		/* read the standard strings and cache them if present */ -		udev->product = usb_cache_string(udev, udev->descriptor.iProduct); -		udev->manufacturer = usb_cache_string(udev, -						      udev->descriptor.iManufacturer); -		udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); -	} + +	/* read the standard strings and cache them if present */ +	udev->product = usb_cache_string(udev, udev->descriptor.iProduct); +	udev->manufacturer = usb_cache_string(udev, +					      udev->descriptor.iManufacturer); +	udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); +  	err = usb_enumerate_device_otg(udev); -fail: -	return err; +	if (err < 0) +		return err; + +	usb_detect_interface_quirks(udev); + +	return 0;  } +static void set_usb_port_removable(struct usb_device *udev) +{ +	struct usb_device *hdev = udev->parent; +	struct usb_hub *hub; +	u8 port = udev->portnum; +	u16 wHubCharacteristics; +	bool removable = true; + +	if (!hdev) +		return; + +	hub = usb_hub_to_struct_hub(udev->parent); + +	wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); + +	if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) +		return; + +	if (hub_is_superspeed(hdev)) { +		if (le16_to_cpu(hub->descriptor->u.ss.DeviceRemovable) +				& (1 << port)) +			removable = false; +	} else { +		if (hub->descriptor->u.hs.DeviceRemovable[port / 8] & (1 << (port % 8))) +			removable = false; +	} + +	if (removable) +		udev->removable = USB_DEVICE_REMOVABLE; +	else +		udev->removable = USB_DEVICE_FIXED; + +	/* +	 * Platform firmware may have populated an alternative value for +	 * removable.  If the parent port has a known connect_type use +	 * that instead. +	 */ +	switch (hub->ports[udev->portnum - 1]->connect_type) { +	case USB_PORT_CONNECT_TYPE_HOT_PLUG: +		udev->removable = USB_DEVICE_REMOVABLE; +		break; +	case USB_PORT_CONNECT_TYPE_HARD_WIRED: +		udev->removable = USB_DEVICE_FIXED; +		break; +	default: /* use what was set above */ +		break; +	} +}  /**   * usb_new_device - perform initial device setup (usbcore-internal) @@ -1782,13 +2385,14 @@ fail:   * udev has already been installed, but udev is not yet visible through   * sysfs or other filesystem code.   * - * It will return if the device is configured properly or not.  Zero if - * the interface was registered with the driver core; else a negative - * errno value. - *   * This call is synchronous, and may not be used in an interrupt context.   *   * Only the hub driver or root-hub registrar should ever call this. + * + * Return: Whether the device is configured properly or not. Zero if the + * interface was registered with the driver core; else a negative errno + * value. + *   */  int usb_new_device(struct usb_device *udev)  { @@ -1804,8 +2408,15 @@ int usb_new_device(struct usb_device *udev)  	/* Tell the runtime-PM framework the device is active */  	pm_runtime_set_active(&udev->dev); +	pm_runtime_get_noresume(&udev->dev); +	pm_runtime_use_autosuspend(&udev->dev);  	pm_runtime_enable(&udev->dev); +	/* By default, forbid autosuspend for all devices.  It will be +	 * allowed for hubs during binding. +	 */ +	usb_disable_autosuspend(udev); +  	err = usb_enumerate_device(udev);	/* Read descriptors */  	if (err < 0)  		goto fail; @@ -1819,7 +2430,20 @@ int usb_new_device(struct usb_device *udev)  	/* Tell the world! */  	announce_device(udev); +	if (udev->serial) +		add_device_randomness(udev->serial, strlen(udev->serial)); +	if (udev->product) +		add_device_randomness(udev->product, strlen(udev->product)); +	if (udev->manufacturer) +		add_device_randomness(udev->manufacturer, +				      strlen(udev->manufacturer)); +  	device_enable_async_suspend(&udev->dev); + +	/* check whether the hub or firmware marks this port as non-removable */ +	if (udev->parent) +		set_usb_port_removable(udev); +  	/* Register the device.  The device driver is responsible  	 * for configuring the device and invoking the add-device  	 * notifier chain (used by usbfs and possibly others). @@ -1830,7 +2454,31 @@ int usb_new_device(struct usb_device *udev)  		goto fail;  	} +	/* Create link files between child device and usb port device. */ +	if (udev->parent) { +		struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); +		int port1 = udev->portnum; +		struct usb_port	*port_dev = hub->ports[port1 - 1]; + +		err = sysfs_create_link(&udev->dev.kobj, +				&port_dev->dev.kobj, "port"); +		if (err) +			goto fail; + +		err = sysfs_create_link(&port_dev->dev.kobj, +				&udev->dev.kobj, "device"); +		if (err) { +			sysfs_remove_link(&udev->dev.kobj, "port"); +			goto fail; +		} + +		if (!test_and_set_bit(port1, hub->child_usage_bits)) +			pm_runtime_get_sync(&port_dev->dev); +	} +  	(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); +	usb_mark_last_busy(udev); +	pm_runtime_put_sync_autosuspend(&udev->dev);  	return err;  fail: @@ -1850,6 +2498,8 @@ fail:   *   * We share a lock (that we have) with device_del(), so we need to   * defer its call. + * + * Return: 0.   */  int usb_deauthorize_device(struct usb_device *usb_dev)  { @@ -1860,16 +2510,6 @@ int usb_deauthorize_device(struct usb_device *usb_dev)  	usb_dev->authorized = 0;  	usb_set_configuration(usb_dev, -1); -	kfree(usb_dev->product); -	usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); -	kfree(usb_dev->manufacturer); -	usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); -	kfree(usb_dev->serial); -	usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); - -	usb_destroy_configuration(usb_dev); -	usb_dev->descriptor.bNumConfigurations = 0; -  out_unauthorized:  	usb_unlock_device(usb_dev);  	return 0; @@ -1897,17 +2537,7 @@ int usb_authorize_device(struct usb_device *usb_dev)  		goto error_device_descriptor;  	} -	kfree(usb_dev->product); -	usb_dev->product = NULL; -	kfree(usb_dev->manufacturer); -	usb_dev->manufacturer = NULL; -	kfree(usb_dev->serial); -	usb_dev->serial = NULL; -  	usb_dev->authorized = 1; -	result = usb_enumerate_device(usb_dev); -	if (result < 0) -		goto error_enumerate;  	/* Choose and set the configuration.  This registers the interfaces  	 * with the driver core and lets interface drivers bind to them.  	 */ @@ -1923,12 +2553,11 @@ int usb_authorize_device(struct usb_device *usb_dev)  	}  	dev_info(&usb_dev->dev, "authorized to connect\n"); -error_enumerate:  error_device_descriptor:  	usb_autosuspend_device(usb_dev);  error_autoresume:  out_authorized: -	usb_unlock_device(usb_dev);	// complements locktree +	usb_unlock_device(usb_dev);	/* complements locktree */  	return result;  } @@ -1948,15 +2577,46 @@ static unsigned hub_is_wusb(struct usb_hub *hub)  #define SET_ADDRESS_TRIES	2  #define GET_DESCRIPTOR_TRIES	2  #define SET_CONFIG_TRIES	(2 * (use_both_schemes + 1)) -#define USE_NEW_SCHEME(i)	((i) / 2 == old_scheme_first) +#define USE_NEW_SCHEME(i)	((i) / 2 == (int)old_scheme_first)  #define HUB_ROOT_RESET_TIME	50	/* times are in msec */  #define HUB_SHORT_RESET_TIME	10 +#define HUB_BH_RESET_TIME	50  #define HUB_LONG_RESET_TIME	200 -#define HUB_RESET_TIMEOUT	500 +#define HUB_RESET_TIMEOUT	800 + +/* + * "New scheme" enumeration causes an extra state transition to be + * exposed to an xhci host and causes USB3 devices to receive control + * commands in the default state.  This has been seen to cause + * enumeration failures, so disable this enumeration scheme for USB3 + * devices. + */ +static bool use_new_scheme(struct usb_device *udev, int retry) +{ +	if (udev->speed == USB_SPEED_SUPER) +		return false; + +	return USE_NEW_SCHEME(retry); +} + +static int hub_port_reset(struct usb_hub *hub, int port1, +			struct usb_device *udev, unsigned int delay, bool warm); + +/* Is a USB 3.0 port in the Inactive or Compliance Mode state? + * Port worm reset is required to recover + */ +static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus) +{ +	return hub_is_superspeed(hub->hdev) && +		(((portstatus & USB_PORT_STAT_LINK_STATE) == +		  USB_SS_PORT_LS_SS_INACTIVE) || +		 ((portstatus & USB_PORT_STAT_LINK_STATE) == +		  USB_SS_PORT_LS_COMP_MOD)) ; +}  static int hub_port_wait_reset(struct usb_hub *hub, int port1, -				struct usb_device *udev, unsigned int delay) +			struct usb_device *udev, unsigned int delay, bool warm)  {  	int delay_time, ret;  	u16 portstatus; @@ -1973,116 +2633,238 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,  		if (ret < 0)  			return ret; -		/* Device went away? */ -		if (!(portstatus & USB_PORT_STAT_CONNECTION)) -			return -ENOTCONN; - -		/* bomb out completely if the connection bounced */ -		if ((portchange & USB_PORT_STAT_C_CONNECTION)) -			return -ENOTCONN; - -		/* if we`ve finished resetting, then break out of the loop */ -		if (!(portstatus & USB_PORT_STAT_RESET) && -		    (portstatus & USB_PORT_STAT_ENABLE)) { -			if (hub_is_wusb(hub)) -				udev->speed = USB_SPEED_WIRELESS; -			else if (portstatus & USB_PORT_STAT_SUPER_SPEED) -				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 -				udev->speed = USB_SPEED_FULL; -			return 0; -		} +		/* The port state is unknown until the reset completes. */ +		if (!(portstatus & USB_PORT_STAT_RESET)) +			break;  		/* switch to the long delay after two short delay failures */  		if (delay_time >= 2 * HUB_SHORT_RESET_TIME)  			delay = HUB_LONG_RESET_TIME; -		dev_dbg (hub->intfdev, -			"port %d not reset yet, waiting %dms\n", -			port1, delay); +		dev_dbg(&hub->ports[port1 - 1]->dev, +				"not %sreset yet, waiting %dms\n", +				warm ? "warm " : "", delay);  	} -	return -EBUSY; +	if ((portstatus & USB_PORT_STAT_RESET)) +		return -EBUSY; + +	if (hub_port_warm_reset_required(hub, portstatus)) +		return -ENOTCONN; + +	/* Device went away? */ +	if (!(portstatus & USB_PORT_STAT_CONNECTION)) +		return -ENOTCONN; + +	/* bomb out completely if the connection bounced.  A USB 3.0 +	 * connection may bounce if multiple warm resets were issued, +	 * but the device may have successfully re-connected. Ignore it. +	 */ +	if (!hub_is_superspeed(hub->hdev) && +			(portchange & USB_PORT_STAT_C_CONNECTION)) +		return -ENOTCONN; + +	if (!(portstatus & USB_PORT_STAT_ENABLE)) +		return -EBUSY; + +	if (!udev) +		return 0; + +	if (hub_is_wusb(hub)) +		udev->speed = USB_SPEED_WIRELESS; +	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 +		udev->speed = USB_SPEED_FULL; +	return 0; +} + +static void hub_port_finish_reset(struct usb_hub *hub, int port1, +			struct usb_device *udev, int *status) +{ +	switch (*status) { +	case 0: +		/* TRSTRCY = 10 ms; plus some extra */ +		msleep(10 + 40); +		if (udev) { +			struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +			update_devnum(udev, 0); +			/* The xHC may think the device is already reset, +			 * so ignore the status. +			 */ +			if (hcd->driver->reset_device) +				hcd->driver->reset_device(hcd, udev); +		} +		/* FALL THROUGH */ +	case -ENOTCONN: +	case -ENODEV: +		usb_clear_port_feature(hub->hdev, +				port1, USB_PORT_FEAT_C_RESET); +		if (hub_is_superspeed(hub->hdev)) { +			usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_BH_PORT_RESET); +			usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_PORT_LINK_STATE); +			usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_CONNECTION); +		} +		if (udev) +			usb_set_device_state(udev, *status +					? USB_STATE_NOTATTACHED +					: USB_STATE_DEFAULT); +		break; +	}  } +/* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */  static int hub_port_reset(struct usb_hub *hub, int port1, -				struct usb_device *udev, unsigned int delay) +			struct usb_device *udev, unsigned int delay, bool warm)  {  	int i, status; -	struct usb_hcd *hcd; +	u16 portchange, portstatus; +	struct usb_port *port_dev = hub->ports[port1 - 1]; -	hcd = bus_to_hcd(udev->bus); -	/* Block EHCI CF initialization during the port reset. -	 * Some companion controllers don't like it when they mix. -	 */ -	down_read(&ehci_cf_port_reset_rwsem); +	if (!hub_is_superspeed(hub->hdev)) { +		if (warm) { +			dev_err(hub->intfdev, "only USB3 hub support " +						"warm reset\n"); +			return -EINVAL; +		} +		/* Block EHCI CF initialization during the port reset. +		 * Some companion controllers don't like it when they mix. +		 */ +		down_read(&ehci_cf_port_reset_rwsem); +	} else if (!warm) { +		/* +		 * If the caller hasn't explicitly requested a warm reset, +		 * double check and see if one is needed. +		 */ +		status = hub_port_status(hub, port1, +					&portstatus, &portchange); +		if (status < 0) +			goto done; + +		if (hub_port_warm_reset_required(hub, portstatus)) +			warm = true; +	}  	/* Reset the port */  	for (i = 0; i < PORT_RESET_TRIES; i++) { -		status = set_port_feature(hub->hdev, -				port1, USB_PORT_FEAT_RESET); -		if (status) -			dev_err(hub->intfdev, -					"cannot reset port %d (err = %d)\n", -					port1, status); -		else { -			status = hub_port_wait_reset(hub, port1, udev, delay); -			if (status && status != -ENOTCONN) +		status = set_port_feature(hub->hdev, port1, (warm ? +					USB_PORT_FEAT_BH_PORT_RESET : +					USB_PORT_FEAT_RESET)); +		if (status == -ENODEV) { +			;	/* The hub is gone */ +		} else if (status) { +			dev_err(&port_dev->dev, +					"cannot %sreset (err = %d)\n", +					warm ? "warm " : "", status); +		} else { +			status = hub_port_wait_reset(hub, port1, udev, delay, +								warm); +			if (status && status != -ENOTCONN && status != -ENODEV)  				dev_dbg(hub->intfdev,  						"port_wait_reset: err = %d\n",  						status);  		} -		/* return on disconnect or reset */ -		switch (status) { -		case 0: -			/* TRSTRCY = 10 ms; plus some extra */ -			msleep(10 + 40); -			update_address(udev, 0); -			if (hcd->driver->reset_device) { -				status = hcd->driver->reset_device(hcd, udev); -				if (status < 0) { -					dev_err(&udev->dev, "Cannot reset " -							"HCD device state\n"); -					break; -				} +		/* Check for disconnect or reset */ +		if (status == 0 || status == -ENOTCONN || status == -ENODEV) { +			hub_port_finish_reset(hub, port1, udev, &status); + +			if (!hub_is_superspeed(hub->hdev)) +				goto done; + +			/* +			 * If a USB 3.0 device migrates from reset to an error +			 * state, re-issue the warm reset. +			 */ +			if (hub_port_status(hub, port1, +					&portstatus, &portchange) < 0) +				goto done; + +			if (!hub_port_warm_reset_required(hub, portstatus)) +				goto done; + +			/* +			 * If the port is in SS.Inactive or Compliance Mode, the +			 * hot or warm reset failed.  Try another warm reset. +			 */ +			if (!warm) { +				dev_dbg(&port_dev->dev, +						"hot reset failed, warm reset\n"); +				warm = true;  			} -			/* FALL THROUGH */ -		case -ENOTCONN: -		case -ENODEV: -			clear_port_feature(hub->hdev, -				port1, USB_PORT_FEAT_C_RESET); -			/* FIXME need disconnect() for NOTATTACHED device */ -			usb_set_device_state(udev, status -					? USB_STATE_NOTATTACHED -					: USB_STATE_DEFAULT); -			goto done;  		} -		dev_dbg (hub->intfdev, -			"port %d not enabled, trying reset again...\n", -			port1); +		dev_dbg(&port_dev->dev, +				"not enabled, trying %sreset again...\n", +				warm ? "warm " : "");  		delay = HUB_LONG_RESET_TIME;  	} -	dev_err (hub->intfdev, -		"Cannot enable port %i.  Maybe the USB cable is bad?\n", -		port1); +	dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n"); + +done: +	if (!hub_is_superspeed(hub->hdev)) +		up_read(&ehci_cf_port_reset_rwsem); - done: -	up_read(&ehci_cf_port_reset_rwsem);  	return status;  } +/* Check if a port is power on */ +static int port_is_power_on(struct usb_hub *hub, unsigned portstatus) +{ +	int ret = 0; + +	if (hub_is_superspeed(hub->hdev)) { +		if (portstatus & USB_SS_PORT_STAT_POWER) +			ret = 1; +	} else { +		if (portstatus & USB_PORT_STAT_POWER) +			ret = 1; +	} + +	return ret; +} + +static void usb_lock_port(struct usb_port *port_dev) +		__acquires(&port_dev->status_lock) +{ +	mutex_lock(&port_dev->status_lock); +	__acquire(&port_dev->status_lock); +} + +static void usb_unlock_port(struct usb_port *port_dev) +		__releases(&port_dev->status_lock) +{ +	mutex_unlock(&port_dev->status_lock); +	__release(&port_dev->status_lock); +} +  #ifdef	CONFIG_PM -#define MASK_BITS	(USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION | \ -				USB_PORT_STAT_SUSPEND) -#define WANT_BITS	(USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION) +/* Check if a port is suspended(USB2.0 port) or in U3 state(USB3.0 port) */ +static int port_is_suspended(struct usb_hub *hub, unsigned portstatus) +{ +	int ret = 0; + +	if (hub_is_superspeed(hub->hdev)) { +		if ((portstatus & USB_PORT_STAT_LINK_STATE) +				== USB_SS_PORT_LS_U3) +			ret = 1; +	} else { +		if (portstatus & USB_PORT_STAT_SUSPEND) +			ret = 1; +	} + +	return ret; +}  /* Determine whether the device on a port is ready for a normal resume,   * is ready for a reset-resume, or should be disconnected. @@ -2091,8 +2873,12 @@ static int check_port_resume_type(struct usb_device *udev,  		struct usb_hub *hub, int port1,  		int status, unsigned portchange, unsigned portstatus)  { +	struct usb_port *port_dev = hub->ports[port1 - 1]; +  	/* Is the device still present? */ -	if (status || (portstatus & MASK_BITS) != WANT_BITS) { +	if (status || port_is_suspended(hub, portstatus) || +			!port_is_power_on(hub, portstatus) || +			!(portstatus & USB_PORT_STAT_CONNECTION)) {  		if (status >= 0)  			status = -ENODEV;  	} @@ -2108,24 +2894,124 @@ static int check_port_resume_type(struct usb_device *udev,  	}  	if (status) { -		dev_dbg(hub->intfdev, -				"port %d status %04x.%04x after resume, %d\n", -				port1, portchange, portstatus, status); +		dev_dbg(&port_dev->dev, "status %04x.%04x after resume, %d\n", +				portchange, portstatus, status);  	} else if (udev->reset_resume) {  		/* Late port handoff can set status-change bits */  		if (portchange & USB_PORT_STAT_C_CONNECTION) -			clear_port_feature(hub->hdev, port1, +			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_CONNECTION);  		if (portchange & USB_PORT_STAT_C_ENABLE) -			clear_port_feature(hub->hdev, port1, +			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_ENABLE);  	}  	return status;  } -#ifdef	CONFIG_USB_SUSPEND +int usb_disable_ltm(struct usb_device *udev) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +	/* Check if the roothub and device supports LTM. */ +	if (!usb_device_supports_ltm(hcd->self.root_hub) || +			!usb_device_supports_ltm(udev)) +		return 0; + +	/* Clear Feature LTM Enable can only be sent if the device is +	 * configured. +	 */ +	if (!udev->actconfig) +		return 0; + +	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +			USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, +			USB_DEVICE_LTM_ENABLE, 0, NULL, 0, +			USB_CTRL_SET_TIMEOUT); +} +EXPORT_SYMBOL_GPL(usb_disable_ltm); + +void usb_enable_ltm(struct usb_device *udev) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +	/* Check if the roothub and device supports LTM. */ +	if (!usb_device_supports_ltm(hcd->self.root_hub) || +			!usb_device_supports_ltm(udev)) +		return; + +	/* Set Feature LTM Enable can only be sent if the device is +	 * configured. +	 */ +	if (!udev->actconfig) +		return; + +	usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +			USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, +			USB_DEVICE_LTM_ENABLE, 0, NULL, 0, +			USB_CTRL_SET_TIMEOUT); +} +EXPORT_SYMBOL_GPL(usb_enable_ltm); + +/* + * usb_enable_remote_wakeup - enable remote wakeup for a device + * @udev: target device + * + * For USB-2 devices: Set the device's remote wakeup feature. + * + * For USB-3 devices: Assume there's only one function on the device and + * enable remote wake for the first interface.  FIXME if the interface + * association descriptor shows there's more than one function. + */ +static int usb_enable_remote_wakeup(struct usb_device *udev) +{ +	if (udev->speed < USB_SPEED_SUPER) +		return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, +				USB_DEVICE_REMOTE_WAKEUP, 0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +	else +		return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_SET_FEATURE, USB_RECIP_INTERFACE, +				USB_INTRF_FUNC_SUSPEND, +				USB_INTRF_FUNC_SUSPEND_RW | +					USB_INTRF_FUNC_SUSPEND_LP, +				NULL, 0, USB_CTRL_SET_TIMEOUT); +} + +/* + * usb_disable_remote_wakeup - disable remote wakeup for a device + * @udev: target device + * + * For USB-2 devices: Clear the device's remote wakeup feature. + * + * For USB-3 devices: Assume there's only one function on the device and + * disable remote wake for the first interface.  FIXME if the interface + * association descriptor shows there's more than one function. + */ +static int usb_disable_remote_wakeup(struct usb_device *udev) +{ +	if (udev->speed < USB_SPEED_SUPER) +		return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, +				USB_DEVICE_REMOTE_WAKEUP, 0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +	else +		return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, +				USB_INTRF_FUNC_SUSPEND,	0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +} + +/* Count of wakeup-enabled devices at or below udev */ +static unsigned wakeup_enabled_descendants(struct usb_device *udev) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(udev); + +	return udev->do_remote_wakeup + +			(hub ? hub->wakeup_enabled_descendants : 0); +}  /*   * usb_port_suspend - suspend a usb device's upstream port @@ -2167,19 +3053,23 @@ static int check_port_resume_type(struct usb_device *udev,   * Linux (2.6) currently has NO mechanisms to initiate that:  no khubd   * timer, no SRP, no requests through sysfs.   * - * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when - * the root hub for their bus goes into global suspend ... so we don't - * (falsely) update the device power state to say it suspended. + * If Runtime PM isn't enabled or used, non-SuperSpeed devices may not get + * suspended until their bus goes into global suspend (i.e., the root + * hub is suspended).  Nevertheless, we change @udev->state to + * USB_STATE_SUSPENDED as this is the device's "logical" state.  The actual + * upstream port setting is stored in @udev->port_is_suspended.   *   * Returns 0 on success, else negative errno.   */  int usb_port_suspend(struct usb_device *udev, pm_message_t msg)  { -	struct usb_hub	*hub = hdev_to_hub(udev->parent); +	struct usb_hub	*hub = usb_hub_to_struct_hub(udev->parent); +	struct usb_port *port_dev = hub->ports[udev->portnum - 1];  	int		port1 = udev->portnum;  	int		status; +	bool		really_suspend = true; -	// dev_dbg(hub->intfdev, "suspend port %d\n", port1); +	usb_lock_port(port_dev);  	/* enable remote wakeup when appropriate; this lets the device  	 * wake up the upstream hub (including maybe the root hub). @@ -2188,39 +3078,94 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)  	 * we don't explicitly enable it here.  	 */  	if (udev->do_remote_wakeup) { -		status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -				USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, -				USB_DEVICE_REMOTE_WAKEUP, 0, -				NULL, 0, -				USB_CTRL_SET_TIMEOUT); +		status = usb_enable_remote_wakeup(udev);  		if (status) {  			dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",  					status);  			/* bail if autosuspend is requested */ -			if (msg.event & PM_EVENT_AUTO) -				return status; +			if (PMSG_IS_AUTO(msg)) +				goto err_wakeup;  		}  	} +	/* disable USB2 hardware LPM */ +	if (udev->usb2_hw_lpm_enabled == 1) +		usb_set_usb2_hardware_lpm(udev, 0); + +	if (usb_disable_ltm(udev)) { +		dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); +		status = -ENOMEM; +		if (PMSG_IS_AUTO(msg)) +			goto err_ltm; +	} +	if (usb_unlocked_disable_lpm(udev)) { +		dev_err(&udev->dev, "Failed to disable LPM before suspend\n."); +		status = -ENOMEM; +		if (PMSG_IS_AUTO(msg)) +			goto err_lpm3; +	} +  	/* see 7.1.7.6 */ -	status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND); +	if (hub_is_superspeed(hub->hdev)) +		status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); + +	/* +	 * For system suspend, we do not need to enable the suspend feature +	 * on individual USB-2 ports.  The devices will automatically go +	 * into suspend a few ms after the root hub stops sending packets. +	 * The USB 2.0 spec calls this "global suspend". +	 * +	 * However, many USB hubs have a bug: They don't relay wakeup requests +	 * from a downstream port if the port's suspend feature isn't on. +	 * Therefore we will turn on the suspend feature if udev or any of its +	 * descendants is enabled for remote wakeup. +	 */ +	else if (PMSG_IS_AUTO(msg) || wakeup_enabled_descendants(udev) > 0) +		status = set_port_feature(hub->hdev, port1, +				USB_PORT_FEAT_SUSPEND); +	else { +		really_suspend = false; +		status = 0; +	}  	if (status) { -		dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", -				port1, status); -		/* paranoia:  "should not happen" */ +		dev_dbg(&port_dev->dev, "can't suspend, status %d\n", status); + +		/* Try to enable USB3 LPM and LTM again */ +		usb_unlocked_enable_lpm(udev); + err_lpm3: +		usb_enable_ltm(udev); + err_ltm: +		/* Try to enable USB2 hardware LPM again */ +		if (udev->usb2_hw_lpm_capable == 1) +			usb_set_usb2_hardware_lpm(udev, 1); +  		if (udev->do_remote_wakeup) -			(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -				USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, -				USB_DEVICE_REMOTE_WAKEUP, 0, -				NULL, 0, -				USB_CTRL_SET_TIMEOUT); +			(void) usb_disable_remote_wakeup(udev); + err_wakeup: + +		/* System sleep transitions should never fail */ +		if (!PMSG_IS_AUTO(msg)) +			status = 0;  	} else { -		/* device has up to 10 msec to fully suspend */ -		dev_dbg(&udev->dev, "usb %ssuspend\n", -				(msg.event & PM_EVENT_AUTO ? "auto-" : "")); +		dev_dbg(&udev->dev, "usb %ssuspend, wakeup %d\n", +				(PMSG_IS_AUTO(msg) ? "auto-" : ""), +				udev->do_remote_wakeup); +		if (really_suspend) { +			udev->port_is_suspended = 1; + +			/* device has up to 10 msec to fully suspend */ +			msleep(10); +		}  		usb_set_device_state(udev, USB_STATE_SUSPENDED); -		msleep(10);  	} + +	if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled +			&& test_and_clear_bit(port1, hub->child_usage_bits)) +		pm_runtime_put_sync(&port_dev->dev); + +	usb_mark_last_busy(hub->hdev); + +	usb_unlock_port(port_dev);  	return status;  } @@ -2238,7 +3183,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)  static int finish_port_resume(struct usb_device *udev)  {  	int	status = 0; -	u16	devstatus; +	u16	devstatus = 0;  	/* caller owns the udev device lock */  	dev_dbg(&udev->dev, "%s\n", @@ -2258,19 +3203,27 @@ static int finish_port_resume(struct usb_device *udev)  	 * operation is carried out here, after the port has been  	 * resumed.  	 */ -	if (udev->reset_resume) +	if (udev->reset_resume) { +		/* +		 * If the device morphs or switches modes when it is reset, +		 * we don't want to perform a reset-resume.  We'll fail the +		 * resume, which will cause a logical disconnect, and then +		 * the device will be rediscovered. +		 */   retry_reset_resume: -		status = usb_reset_and_verify_device(udev); +		if (udev->quirks & USB_QUIRK_RESET) +			status = -ENODEV; +		else +			status = usb_reset_and_verify_device(udev); +	} - 	/* 10.5.4.5 says be sure devices in the tree are still there. - 	 * For now let's assume the device didn't go crazy on resume, +	/* 10.5.4.5 says be sure devices in the tree are still there. +	 * For now let's assume the device didn't go crazy on resume,  	 * and device drivers will know about any resume quirks.  	 */  	if (status == 0) {  		devstatus = 0;  		status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); -		if (status >= 0) -			status = (status > 0 ? 0 : -ENODEV);  		/* If a normal resume failed, try doing a reset-resume */  		if (status && !udev->reset_resume && udev->persist_enabled) { @@ -2283,21 +3236,28 @@ static int finish_port_resume(struct usb_device *udev)  	if (status) {  		dev_dbg(&udev->dev, "gone after usb resume? status %d\n",  				status); -	} else if (udev->actconfig) { -		le16_to_cpus(&devstatus); -		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { -			status = usb_control_msg(udev, -					usb_sndctrlpipe(udev, 0), -					USB_REQ_CLEAR_FEATURE, -						USB_RECIP_DEVICE, -					USB_DEVICE_REMOTE_WAKEUP, 0, -					NULL, 0, -					USB_CTRL_SET_TIMEOUT); -			if (status) -				dev_dbg(&udev->dev, -					"disable remote wakeup, status %d\n", -					status); +	/* +	 * There are a few quirky devices which violate the standard +	 * by claiming to have remote wakeup enabled after a reset, +	 * which crash if the feature is cleared, hence check for +	 * udev->reset_resume +	 */ +	} else if (udev->actconfig && !udev->reset_resume) { +		if (udev->speed < USB_SPEED_SUPER) { +			if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) +				status = usb_disable_remote_wakeup(udev); +		} else { +			status = usb_get_status(udev, USB_RECIP_INTERFACE, 0, +					&devstatus); +			if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP +					| USB_INTRF_STAT_FUNC_RW)) +				status = usb_disable_remote_wakeup(udev);  		} + +		if (status) +			dev_dbg(&udev->dev, +				"disable remote wakeup, status %d\n", +				status);  		status = 0;  	}  	return status; @@ -2339,30 +3299,40 @@ static int finish_port_resume(struct usb_device *udev)   */  int usb_port_resume(struct usb_device *udev, pm_message_t msg)  { -	struct usb_hub	*hub = hdev_to_hub(udev->parent); +	struct usb_hub	*hub = usb_hub_to_struct_hub(udev->parent); +	struct usb_port *port_dev = hub->ports[udev->portnum  - 1];  	int		port1 = udev->portnum;  	int		status;  	u16		portchange, portstatus; +	if (!test_and_set_bit(port1, hub->child_usage_bits)) { +		status = pm_runtime_get_sync(&port_dev->dev); +		if (status < 0) { +			dev_dbg(&udev->dev, "can't resume usb port, status %d\n", +					status); +			return status; +		} +	} + +	usb_lock_port(port_dev); +  	/* Skip the initial Clear-Suspend step for a remote wakeup */  	status = hub_port_status(hub, port1, &portstatus, &portchange); -	if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND)) +	if (status == 0 && !port_is_suspended(hub, portstatus))  		goto SuspendCleared; -	// dev_dbg(hub->intfdev, "resume port %d\n", port1); - -	set_bit(port1, hub->busy_bits); -  	/* see 7.1.7.7; affects power usage, but not budgeting */ -	status = clear_port_feature(hub->hdev, -			port1, USB_PORT_FEAT_SUSPEND); +	if (hub_is_superspeed(hub->hdev)) +		status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0); +	else +		status = usb_clear_port_feature(hub->hdev, +				port1, USB_PORT_FEAT_SUSPEND);  	if (status) { -		dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", -				port1, status); +		dev_dbg(&port_dev->dev, "can't resume, status %d\n", status);  	} else {  		/* drive resume for at least 20 msec */  		dev_dbg(&udev->dev, "usb %sresume\n", -				(msg.event & PM_EVENT_AUTO ? "auto-" : "")); +				(PMSG_IS_AUTO(msg) ? "auto-" : ""));  		msleep(25);  		/* Virtual root hubs can trigger on GET_PORT_STATUS to @@ -2377,13 +3347,18 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)   SuspendCleared:  	if (status == 0) { -		if (portchange & USB_PORT_STAT_C_SUSPEND) -			clear_port_feature(hub->hdev, port1, -					USB_PORT_FEAT_C_SUSPEND); +		udev->port_is_suspended = 0; +		if (hub_is_superspeed(hub->hdev)) { +			if (portchange & USB_PORT_STAT_C_LINK_STATE) +				usb_clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_PORT_LINK_STATE); +		} else { +			if (portchange & USB_PORT_STAT_C_SUSPEND) +				usb_clear_port_feature(hub->hdev, port1, +						USB_PORT_FEAT_C_SUSPEND); +		}  	} -	clear_bit(port1, hub->busy_bits); -  	status = check_port_resume_type(udev,  			hub, port1, status, portchange, portstatus);  	if (status == 0) @@ -2391,15 +3366,28 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)  	if (status < 0) {  		dev_dbg(&udev->dev, "can't resume, status %d\n", status);  		hub_port_logical_disconnect(hub, port1); +	} else  { +		/* Try to enable USB2 hardware LPM */ +		if (udev->usb2_hw_lpm_capable == 1) +			usb_set_usb2_hardware_lpm(udev, 1); + +		/* Try to enable USB3 LTM and LPM */ +		usb_enable_ltm(udev); +		usb_unlocked_enable_lpm(udev);  	} + +	usb_unlock_port(port_dev); +  	return status;  } -/* caller has locked udev */ +#ifdef	CONFIG_PM_RUNTIME +  int usb_remote_wakeup(struct usb_device *udev)  {  	int	status = 0; +	usb_lock_device(udev);  	if (udev->state == USB_STATE_SUSPENDED) {  		dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");  		status = usb_autoresume_device(udev); @@ -2408,59 +3396,121 @@ int usb_remote_wakeup(struct usb_device *udev)  			usb_autosuspend_device(udev);  		}  	} +	usb_unlock_device(udev);  	return status;  } -#else	/* CONFIG_USB_SUSPEND */ +/* Returns 1 if there was a remote wakeup and a connect status change. */ +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, +		u16 portstatus, u16 portchange) +		__must_hold(&port_dev->status_lock) +{ +	struct usb_port *port_dev = hub->ports[port - 1]; +	struct usb_device *hdev; +	struct usb_device *udev; +	int connect_change = 0; +	int ret; + +	hdev = hub->hdev; +	udev = port_dev->child; +	if (!hub_is_superspeed(hdev)) { +		if (!(portchange & USB_PORT_STAT_C_SUSPEND)) +			return 0; +		usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); +	} else { +		if (!udev || udev->state != USB_STATE_SUSPENDED || +				 (portstatus & USB_PORT_STAT_LINK_STATE) != +				 USB_SS_PORT_LS_U0) +			return 0; +	} -/* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */ +	if (udev) { +		/* TRSMRCY = 10 msec */ +		msleep(10); -int usb_port_suspend(struct usb_device *udev, pm_message_t msg) +		usb_unlock_port(port_dev); +		ret = usb_remote_wakeup(udev); +		usb_lock_port(port_dev); +		if (ret < 0) +			connect_change = 1; +	} else { +		ret = -ENODEV; +		hub_port_disable(hub, port, 1); +	} +	dev_dbg(&port_dev->dev, "resume, status %d\n", ret); +	return connect_change; +} + +#else + +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, +		u16 portstatus, u16 portchange)  {  	return 0;  } -/* However we may need to do a reset-resume */ +#endif -int usb_port_resume(struct usb_device *udev, pm_message_t msg) +static int check_ports_changed(struct usb_hub *hub)  { -	struct usb_hub	*hub = hdev_to_hub(udev->parent); -	int		port1 = udev->portnum; -	int		status; -	u16		portchange, portstatus; +	int port1; -	status = hub_port_status(hub, port1, &portstatus, &portchange); -	status = check_port_resume_type(udev, -			hub, port1, status, portchange, portstatus); +	for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) { +		u16 portstatus, portchange; +		int status; -	if (status) { -		dev_dbg(&udev->dev, "can't resume, status %d\n", status); -		hub_port_logical_disconnect(hub, port1); -	} else if (udev->reset_resume) { -		dev_dbg(&udev->dev, "reset-resume\n"); -		status = usb_reset_and_verify_device(udev); +		status = hub_port_status(hub, port1, &portstatus, &portchange); +		if (!status && portchange) +			return 1;  	} -	return status; +	return 0;  } -#endif -  static int hub_suspend(struct usb_interface *intf, pm_message_t msg)  {  	struct usb_hub		*hub = usb_get_intfdata (intf);  	struct usb_device	*hdev = hub->hdev;  	unsigned		port1; +	int			status; -	/* fail if children aren't already suspended */ +	/* +	 * Warn if children aren't already suspended. +	 * Also, add up the number of wakeup-enabled descendants. +	 */ +	hub->wakeup_enabled_descendants = 0;  	for (port1 = 1; port1 <= hdev->maxchild; port1++) { -		struct usb_device	*udev; +		struct usb_port *port_dev = hub->ports[port1 - 1]; +		struct usb_device *udev = port_dev->child; -		udev = hdev->children [port1-1];  		if (udev && udev->can_submit) { -			if (!(msg.event & PM_EVENT_AUTO)) -				dev_dbg(&intf->dev, "port %d nyet suspended\n", -						port1); -			return -EBUSY; +			dev_warn(&port_dev->dev, "device %s not suspended yet\n", +					dev_name(&udev->dev)); +			if (PMSG_IS_AUTO(msg)) +				return -EBUSY; +		} +		if (udev) +			hub->wakeup_enabled_descendants += +					wakeup_enabled_descendants(udev); +	} + +	if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { +		/* check if there are changes pending on hub ports */ +		if (check_ports_changed(hub)) { +			if (PMSG_IS_AUTO(msg)) +				return -EBUSY; +			pm_wakeup_event(&hdev->dev, 2000); +		} +	} + +	if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) { +		/* Enable hub to send remote wakeup for all ports. */ +		for (port1 = 1; port1 <= hdev->maxchild; port1++) { +			status = set_port_feature(hdev, +					port1 | +					USB_PORT_FEAT_REMOTE_WAKE_CONNECT | +					USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT | +					USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT, +					USB_PORT_FEAT_REMOTE_WAKE_MASK);  		}  	} @@ -2507,12 +3557,459 @@ void usb_root_hub_lost_power(struct usb_device *rhdev)  }  EXPORT_SYMBOL_GPL(usb_root_hub_lost_power); +static const char * const usb3_lpm_names[]  = { +	"U0", +	"U1", +	"U2", +	"U3", +}; + +/* + * Send a Set SEL control transfer to the device, prior to enabling + * device-initiated U1 or U2.  This lets the device know the exit latencies from + * the time the device initiates a U1 or U2 exit, to the time it will receive a + * packet from the host. + * + * This function will fail if the SEL or PEL values for udev are greater than + * the maximum allowed values for the link state to be enabled. + */ +static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) +{ +	struct usb_set_sel_req *sel_values; +	unsigned long long u1_sel; +	unsigned long long u1_pel; +	unsigned long long u2_sel; +	unsigned long long u2_pel; +	int ret; + +	if (udev->state != USB_STATE_CONFIGURED) +		return 0; + +	/* Convert SEL and PEL stored in ns to us */ +	u1_sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); +	u1_pel = DIV_ROUND_UP(udev->u1_params.pel, 1000); +	u2_sel = DIV_ROUND_UP(udev->u2_params.sel, 1000); +	u2_pel = DIV_ROUND_UP(udev->u2_params.pel, 1000); + +	/* +	 * Make sure that the calculated SEL and PEL values for the link +	 * state we're enabling aren't bigger than the max SEL/PEL +	 * value that will fit in the SET SEL control transfer. +	 * Otherwise the device would get an incorrect idea of the exit +	 * latency for the link state, and could start a device-initiated +	 * U1/U2 when the exit latencies are too high. +	 */ +	if ((state == USB3_LPM_U1 && +				(u1_sel > USB3_LPM_MAX_U1_SEL_PEL || +				 u1_pel > USB3_LPM_MAX_U1_SEL_PEL)) || +			(state == USB3_LPM_U2 && +			 (u2_sel > USB3_LPM_MAX_U2_SEL_PEL || +			  u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { +		dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n", +				usb3_lpm_names[state], u1_sel, u1_pel); +		return -EINVAL; +	} + +	/* +	 * If we're enabling device-initiated LPM for one link state, +	 * but the other link state has a too high SEL or PEL value, +	 * just set those values to the max in the Set SEL request. +	 */ +	if (u1_sel > USB3_LPM_MAX_U1_SEL_PEL) +		u1_sel = USB3_LPM_MAX_U1_SEL_PEL; + +	if (u1_pel > USB3_LPM_MAX_U1_SEL_PEL) +		u1_pel = USB3_LPM_MAX_U1_SEL_PEL; + +	if (u2_sel > USB3_LPM_MAX_U2_SEL_PEL) +		u2_sel = USB3_LPM_MAX_U2_SEL_PEL; + +	if (u2_pel > USB3_LPM_MAX_U2_SEL_PEL) +		u2_pel = USB3_LPM_MAX_U2_SEL_PEL; + +	/* +	 * usb_enable_lpm() can be called as part of a failed device reset, +	 * which may be initiated by an error path of a mass storage driver. +	 * Therefore, use GFP_NOIO. +	 */ +	sel_values = kmalloc(sizeof *(sel_values), GFP_NOIO); +	if (!sel_values) +		return -ENOMEM; + +	sel_values->u1_sel = u1_sel; +	sel_values->u1_pel = u1_pel; +	sel_values->u2_sel = cpu_to_le16(u2_sel); +	sel_values->u2_pel = cpu_to_le16(u2_pel); + +	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +			USB_REQ_SET_SEL, +			USB_RECIP_DEVICE, +			0, 0, +			sel_values, sizeof *(sel_values), +			USB_CTRL_SET_TIMEOUT); +	kfree(sel_values); +	return ret; +} + +/* + * Enable or disable device-initiated U1 or U2 transitions. + */ +static int usb_set_device_initiated_lpm(struct usb_device *udev, +		enum usb3_link_state state, bool enable) +{ +	int ret; +	int feature; + +	switch (state) { +	case USB3_LPM_U1: +		feature = USB_DEVICE_U1_ENABLE; +		break; +	case USB3_LPM_U2: +		feature = USB_DEVICE_U2_ENABLE; +		break; +	default: +		dev_warn(&udev->dev, "%s: Can't %s non-U1 or U2 state.\n", +				__func__, enable ? "enable" : "disable"); +		return -EINVAL; +	} + +	if (udev->state != USB_STATE_CONFIGURED) { +		dev_dbg(&udev->dev, "%s: Can't %s %s state " +				"for unconfigured device.\n", +				__func__, enable ? "enable" : "disable", +				usb3_lpm_names[state]); +		return 0; +	} + +	if (enable) { +		/* +		 * Now send the control transfer to enable device-initiated LPM +		 * for either U1 or U2. +		 */ +		ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_SET_FEATURE, +				USB_RECIP_DEVICE, +				feature, +				0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +	} else { +		ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_CLEAR_FEATURE, +				USB_RECIP_DEVICE, +				feature, +				0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +	} +	if (ret < 0) { +		dev_warn(&udev->dev, "%s of device-initiated %s failed.\n", +				enable ? "Enable" : "Disable", +				usb3_lpm_names[state]); +		return -EBUSY; +	} +	return 0; +} + +static int usb_set_lpm_timeout(struct usb_device *udev, +		enum usb3_link_state state, int timeout) +{ +	int ret; +	int feature; + +	switch (state) { +	case USB3_LPM_U1: +		feature = USB_PORT_FEAT_U1_TIMEOUT; +		break; +	case USB3_LPM_U2: +		feature = USB_PORT_FEAT_U2_TIMEOUT; +		break; +	default: +		dev_warn(&udev->dev, "%s: Can't set timeout for non-U1 or U2 state.\n", +				__func__); +		return -EINVAL; +	} + +	if (state == USB3_LPM_U1 && timeout > USB3_LPM_U1_MAX_TIMEOUT && +			timeout != USB3_LPM_DEVICE_INITIATED) { +		dev_warn(&udev->dev, "Failed to set %s timeout to 0x%x, " +				"which is a reserved value.\n", +				usb3_lpm_names[state], timeout); +		return -EINVAL; +	} + +	ret = set_port_feature(udev->parent, +			USB_PORT_LPM_TIMEOUT(timeout) | udev->portnum, +			feature); +	if (ret < 0) { +		dev_warn(&udev->dev, "Failed to set %s timeout to 0x%x," +				"error code %i\n", usb3_lpm_names[state], +				timeout, ret); +		return -EBUSY; +	} +	if (state == USB3_LPM_U1) +		udev->u1_params.timeout = timeout; +	else +		udev->u2_params.timeout = timeout; +	return 0; +} + +/* + * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated + * U1/U2 entry. + * + * We will attempt to enable U1 or U2, but there are no guarantees that the + * control transfers to set the hub timeout or enable device-initiated U1/U2 + * will be successful. + * + * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI + * driver know about it.  If that call fails, it should be harmless, and just + * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency. + */ +static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, +		enum usb3_link_state state) +{ +	int timeout, ret; +	__u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; +	__le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; + +	/* If the device says it doesn't have *any* exit latency to come out of +	 * U1 or U2, it's probably lying.  Assume it doesn't implement that link +	 * state. +	 */ +	if ((state == USB3_LPM_U1 && u1_mel == 0) || +			(state == USB3_LPM_U2 && u2_mel == 0)) +		return; + +	/* +	 * First, let the device know about the exit latencies +	 * associated with the link state we're about to enable. +	 */ +	ret = usb_req_set_sel(udev, state); +	if (ret < 0) { +		dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n", +				usb3_lpm_names[state]); +		return; +	} + +	/* We allow the host controller to set the U1/U2 timeout internally +	 * first, so that it can change its schedule to account for the +	 * additional latency to send data to a device in a lower power +	 * link state. +	 */ +	timeout = hcd->driver->enable_usb3_lpm_timeout(hcd, udev, state); + +	/* xHCI host controller doesn't want to enable this LPM state. */ +	if (timeout == 0) +		return; + +	if (timeout < 0) { +		dev_warn(&udev->dev, "Could not enable %s link state, " +				"xHCI error %i.\n", usb3_lpm_names[state], +				timeout); +		return; +	} + +	if (usb_set_lpm_timeout(udev, state, timeout)) +		/* If we can't set the parent hub U1/U2 timeout, +		 * device-initiated LPM won't be allowed either, so let the xHCI +		 * host know that this link state won't be enabled. +		 */ +		hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); + +	/* Only a configured device will accept the Set Feature U1/U2_ENABLE */ +	else if (udev->actconfig) +		usb_set_device_initiated_lpm(udev, state, true); + +} + +/* + * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated + * U1/U2 entry. + * + * If this function returns -EBUSY, the parent hub will still allow U1/U2 entry. + * If zero is returned, the parent will not allow the link to go into U1/U2. + * + * If zero is returned, device-initiated U1/U2 entry may still be enabled, but + * it won't have an effect on the bus link state because the parent hub will + * still disallow device-initiated U1/U2 entry. + * + * If zero is returned, the xHCI host controller may still think U1/U2 entry is + * possible.  The result will be slightly more bus bandwidth will be taken up + * (to account for U1/U2 exit latency), but it should be harmless. + */ +static int usb_disable_link_state(struct usb_hcd *hcd, struct usb_device *udev, +		enum usb3_link_state state) +{ +	int feature; + +	switch (state) { +	case USB3_LPM_U1: +		feature = USB_PORT_FEAT_U1_TIMEOUT; +		break; +	case USB3_LPM_U2: +		feature = USB_PORT_FEAT_U2_TIMEOUT; +		break; +	default: +		dev_warn(&udev->dev, "%s: Can't disable non-U1 or U2 state.\n", +				__func__); +		return -EINVAL; +	} + +	if (usb_set_lpm_timeout(udev, state, 0)) +		return -EBUSY; + +	usb_set_device_initiated_lpm(udev, state, false); + +	if (hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state)) +		dev_warn(&udev->dev, "Could not disable xHCI %s timeout, " +				"bus schedule bandwidth may be impacted.\n", +				usb3_lpm_names[state]); +	return 0; +} + +/* + * Disable hub-initiated and device-initiated U1 and U2 entry. + * Caller must own the bandwidth_mutex. + * + * This will call usb_enable_lpm() on failure, which will decrement + * lpm_disable_count, and will re-enable LPM if lpm_disable_count reaches zero. + */ +int usb_disable_lpm(struct usb_device *udev) +{ +	struct usb_hcd *hcd; + +	if (!udev || !udev->parent || +			udev->speed != USB_SPEED_SUPER || +			!udev->lpm_capable) +		return 0; + +	hcd = bus_to_hcd(udev->bus); +	if (!hcd || !hcd->driver->disable_usb3_lpm_timeout) +		return 0; + +	udev->lpm_disable_count++; +	if ((udev->u1_params.timeout == 0 && udev->u2_params.timeout == 0)) +		return 0; + +	/* If LPM is enabled, attempt to disable it. */ +	if (usb_disable_link_state(hcd, udev, USB3_LPM_U1)) +		goto enable_lpm; +	if (usb_disable_link_state(hcd, udev, USB3_LPM_U2)) +		goto enable_lpm; + +	return 0; + +enable_lpm: +	usb_enable_lpm(udev); +	return -EBUSY; +} +EXPORT_SYMBOL_GPL(usb_disable_lpm); + +/* Grab the bandwidth_mutex before calling usb_disable_lpm() */ +int usb_unlocked_disable_lpm(struct usb_device *udev) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); +	int ret; + +	if (!hcd) +		return -EINVAL; + +	mutex_lock(hcd->bandwidth_mutex); +	ret = usb_disable_lpm(udev); +	mutex_unlock(hcd->bandwidth_mutex); + +	return ret; +} +EXPORT_SYMBOL_GPL(usb_unlocked_disable_lpm); + +/* + * Attempt to enable device-initiated and hub-initiated U1 and U2 entry.  The + * xHCI host policy may prevent U1 or U2 from being enabled. + * + * Other callers may have disabled link PM, so U1 and U2 entry will be disabled + * until the lpm_disable_count drops to zero.  Caller must own the + * bandwidth_mutex. + */ +void usb_enable_lpm(struct usb_device *udev) +{ +	struct usb_hcd *hcd; + +	if (!udev || !udev->parent || +			udev->speed != USB_SPEED_SUPER || +			!udev->lpm_capable) +		return; + +	udev->lpm_disable_count--; +	hcd = bus_to_hcd(udev->bus); +	/* Double check that we can both enable and disable LPM. +	 * Device must be configured to accept set feature U1/U2 timeout. +	 */ +	if (!hcd || !hcd->driver->enable_usb3_lpm_timeout || +			!hcd->driver->disable_usb3_lpm_timeout) +		return; + +	if (udev->lpm_disable_count > 0) +		return; + +	usb_enable_link_state(hcd, udev, USB3_LPM_U1); +	usb_enable_link_state(hcd, udev, USB3_LPM_U2); +} +EXPORT_SYMBOL_GPL(usb_enable_lpm); + +/* Grab the bandwidth_mutex before calling usb_enable_lpm() */ +void usb_unlocked_enable_lpm(struct usb_device *udev) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +	if (!hcd) +		return; + +	mutex_lock(hcd->bandwidth_mutex); +	usb_enable_lpm(udev); +	mutex_unlock(hcd->bandwidth_mutex); +} +EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); + +  #else	/* CONFIG_PM */  #define hub_suspend		NULL  #define hub_resume		NULL  #define hub_reset_resume	NULL -#endif + +int usb_disable_lpm(struct usb_device *udev) +{ +	return 0; +} +EXPORT_SYMBOL_GPL(usb_disable_lpm); + +void usb_enable_lpm(struct usb_device *udev) { } +EXPORT_SYMBOL_GPL(usb_enable_lpm); + +int usb_unlocked_disable_lpm(struct usb_device *udev) +{ +	return 0; +} +EXPORT_SYMBOL_GPL(usb_unlocked_disable_lpm); + +void usb_unlocked_enable_lpm(struct usb_device *udev) { } +EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); + +int usb_disable_ltm(struct usb_device *udev) +{ +	return 0; +} +EXPORT_SYMBOL_GPL(usb_disable_ltm); + +void usb_enable_ltm(struct usb_device *udev) { } +EXPORT_SYMBOL_GPL(usb_enable_ltm); + +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, +		u16 portstatus, u16 portchange) +{ +	return 0; +} + +#endif	/* CONFIG_PM */  /* USB 2.0 spec, 7.1.7.3 / fig 7-29: @@ -2520,7 +4017,7 @@ EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);   * Between connect detection and reset signaling there must be a delay   * of 100ms at least for debounce and power-settling.  The corresponding   * timer shall restart whenever the downstream port detects a disconnect. - *  + *   * Apparently there are some bluetooth and irda-dongles and a number of   * low-speed devices for which this debounce period may last over a second.   * Not covered by the spec - but easy to deal with. @@ -2530,12 +4027,13 @@ EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);   * every 25ms for transient disconnects.  When the port status has been   * unchanged for 100ms it returns the port status.   */ -static int hub_port_debounce(struct usb_hub *hub, int port1) +int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)  {  	int ret; -	int total_time, stable_time = 0;  	u16 portchange, portstatus;  	unsigned connection = 0xffff; +	int total_time, stable_time = 0; +	struct usb_port *port_dev = hub->ports[port1 - 1];  	for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {  		ret = hub_port_status(hub, port1, &portstatus, &portchange); @@ -2544,7 +4042,9 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)  		if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&  		     (portstatus & USB_PORT_STAT_CONNECTION) == connection) { -			stable_time += HUB_DEBOUNCE_STEP; +			if (!must_be_connected || +			     (connection == USB_PORT_STAT_CONNECTION)) +				stable_time += HUB_DEBOUNCE_STEP;  			if (stable_time >= HUB_DEBOUNCE_STABLE)  				break;  		} else { @@ -2553,7 +4053,7 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)  		}  		if (portchange & USB_PORT_STAT_C_CONNECTION) { -			clear_port_feature(hub->hdev, port1, +			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_CONNECTION);  		} @@ -2562,9 +4062,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)  		msleep(HUB_DEBOUNCE_STEP);  	} -	dev_dbg (hub->intfdev, -		"debounce: port %d: total %dms stable %dms status 0x%x\n", -		port1, total_time, stable_time, portstatus); +	dev_dbg(&port_dev->dev, "debounce total %dms stable %dms status 0x%x\n", +			total_time, stable_time, portstatus);  	if (stable_time < HUB_DEBOUNCE_STABLE)  		return -ETIMEDOUT; @@ -2604,7 +4103,7 @@ static int hub_set_address(struct usb_device *udev, int devnum)  				USB_REQ_SET_ADDRESS, 0, devnum, 0,  				NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (retval == 0) { -		update_address(udev, devnum); +		update_devnum(udev, devnum);  		/* Device now using proper address. */  		usb_set_device_state(udev, USB_STATE_ADDRESS);  		usb_ep0_reinit(udev); @@ -2612,27 +4111,67 @@ static int hub_set_address(struct usb_device *udev, int devnum)  	return retval;  } +/* + * There are reports of USB 3.0 devices that say they support USB 2.0 Link PM + * when they're plugged into a USB 2.0 port, but they don't work when LPM is + * enabled. + * + * Only enable USB 2.0 Link PM if the port is internal (hardwired), or the + * device says it supports the new USB 2.0 Link PM errata by setting the BESL + * support bit in the BOS descriptor. + */ +static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); +	int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN; + +	if (!udev->usb2_hw_lpm_capable) +		return; + +	if (hub) +		connect_type = hub->ports[udev->portnum - 1]->connect_type; + +	if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || +			connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { +		udev->usb2_hw_lpm_allowed = 1; +		usb_set_usb2_hardware_lpm(udev, 1); +	} +} + +static int hub_enable_device(struct usb_device *udev) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +	if (!hcd->driver->enable_device) +		return 0; +	if (udev->state == USB_STATE_ADDRESS) +		return 0; +	if (udev->state != USB_STATE_DEFAULT) +		return -EINVAL; + +	return hcd->driver->enable_device(hcd, udev); +} +  /* Reset device, (re)assign address, get device descriptor.   * Device connection must be stable, no more debouncing needed.   * Returns device in USB_STATE_ADDRESS, except on error.   *   * If this is called for an already-existing device (as part of - * usb_reset_and_verify_device), the caller must own the device lock.  For a - * newly detected device that is not accessible through any global - * pointers, it's not necessary to lock the device. + * usb_reset_and_verify_device), the caller must own the device lock and + * the port lock.  For a newly detected device that is not accessible + * through any global pointers, it's not necessary to lock the device, + * but it is still necessary to lock the port.   */  static int  hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  		int retry_counter)  { -	static DEFINE_MUTEX(usb_address0_mutex); -  	struct usb_device	*hdev = hub->hdev;  	struct usb_hcd		*hcd = bus_to_hcd(hdev->bus);  	int			i, j, retval;  	unsigned		delay = HUB_SHORT_RESET_TIME;  	enum usb_device_speed	oldspeed = udev->speed; -	char 			*speed, *type; +	const char		*speed;  	int			devnum = udev->devnum;  	/* root hub ports have a slightly longer reset period @@ -2649,19 +4188,15 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	if (oldspeed == USB_SPEED_LOW)  		delay = HUB_LONG_RESET_TIME; -	mutex_lock(&usb_address0_mutex); +	mutex_lock(&hdev->bus->usb_address0_mutex); + +	/* Reset the device; full speed may morph to high speed */ +	/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ +	retval = hub_port_reset(hub, port1, udev, delay, false); +	if (retval < 0)		/* error or disconnect */ +		goto fail; +	/* success, speed is known */ -	if (!udev->config && oldspeed == USB_SPEED_SUPER) { -		/* Don't reset USB 3.0 devices during an initial setup */ -		usb_set_device_state(udev, USB_STATE_DEFAULT); -	} else { -		/* Reset the device; full speed may morph to high speed */ -		/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ -		retval = hub_port_reset(hub, port1, udev, delay); -		if (retval < 0)		/* error or disconnect */ -			goto fail; -		/* success, speed is known */ -	}  	retval = -ENODEV;  	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { @@ -2696,26 +4231,17 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	default:  		goto fail;  	} -  -	type = ""; -	switch (udev->speed) { -	case USB_SPEED_LOW:	speed = "low";	break; -	case USB_SPEED_FULL:	speed = "full";	break; -	case USB_SPEED_HIGH:	speed = "high";	break; -	case USB_SPEED_SUPER: -				speed = "super"; -				break; -	case USB_SPEED_WIRELESS: -				speed = "variable"; -				type = "Wireless "; -				break; -	default: 		speed = "?";	break; -	} + +	if (udev->speed == USB_SPEED_WIRELESS) +		speed = "variable speed Wireless"; +	else +		speed = usb_speed_string(udev->speed); +  	if (udev->speed != USB_SPEED_SUPER)  		dev_info(&udev->dev, -				"%s %s speed %sUSB device using %s and address %d\n", -				(udev->config) ? "reset" : "new", speed, type, -				udev->bus->controller->driver->name, devnum); +				"%s %s USB device number %d using %s\n", +				(udev->config) ? "reset" : "new", speed, +				devnum, udev->bus->controller->driver->name);  	/* Set up TT records, if needed  */  	if (hdev->tt) { @@ -2723,16 +4249,21 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  		udev->ttport = hdev->ttport;  	} else if (udev->speed != USB_SPEED_HIGH  			&& hdev->speed == USB_SPEED_HIGH) { +		if (!hub->tt.hub) { +			dev_err(&udev->dev, "parent hub has no TT\n"); +			retval = -EINVAL; +			goto fail; +		}  		udev->tt = &hub->tt;  		udev->ttport = port1;  	} -  +  	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?  	 * Because device hardware and firmware is sometimes buggy in  	 * this area, and this is how Linux has done it for ages.  	 * Change it cautiously.  	 * -	 * NOTE:  If USE_NEW_SCHEME() is true we will start by issuing +	 * NOTE:  If use_new_scheme() is true we will start by issuing  	 * a 64-byte GET_DESCRIPTOR request.  This is what Windows does,  	 * so it may help with some non-standards-compliant devices.  	 * Otherwise we start with SET_ADDRESS and then try to read the @@ -2740,14 +4271,21 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	 * value.  	 */  	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { -		/* -		 * An xHCI controller cannot send any packets to a device until -		 * a set address command successfully completes. -		 */ -		if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { +		bool did_new_scheme = false; + +		if (use_new_scheme(udev, retry_counter)) {  			struct usb_device_descriptor *buf;  			int r = 0; +			did_new_scheme = true; +			retval = hub_enable_device(udev); +			if (retval < 0) { +				dev_err(&udev->dev, +					"hub failed to enable device, error %d\n", +					retval); +				goto fail; +			} +  #define GET_DESCRIPTOR_BUFSIZE	64  			buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);  			if (!buf) { @@ -2786,7 +4324,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  					buf->bMaxPacketSize0;  			kfree(buf); -			retval = hub_port_reset(hub, port1, udev, delay); +			retval = hub_port_reset(hub, port1, udev, delay, false);  			if (retval < 0)		/* error or disconnect */  				goto fail;  			if (oldspeed != udev->speed) { @@ -2796,20 +4334,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  				goto fail;  			}  			if (r) { -				dev_err(&udev->dev, -					"device descriptor read/64, error %d\n", -					r); +				if (r != -ENODEV) +					dev_err(&udev->dev, "device descriptor read/64, error %d\n", +							r);  				retval = -EMSGSIZE;  				continue;  			}  #undef GET_DESCRIPTOR_BUFSIZE  		} - 		/* - 		 * If device is WUSB, we already assigned an - 		 * unauthorized address in the Connect Ack sequence; - 		 * authorization will assign the final address. - 		 */ +		/* +		 * If device is WUSB, we already assigned an +		 * unauthorized address in the Connect Ack sequence; +		 * authorization will assign the final address. +		 */  		if (udev->wusb == 0) {  			for (j = 0; j < SET_ADDRESS_TRIES; ++j) {  				retval = hub_set_address(udev, devnum); @@ -2818,17 +4356,17 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  				msleep(200);  			}  			if (retval < 0) { -				dev_err(&udev->dev, -					"device not accepting address %d, error %d\n", -					devnum, retval); +				if (retval != -ENODEV) +					dev_err(&udev->dev, "device not accepting address %d, error %d\n", +							devnum, retval);  				goto fail;  			}  			if (udev->speed == USB_SPEED_SUPER) {  				devnum = udev->devnum;  				dev_info(&udev->dev, -						"%s SuperSpeed USB device using %s and address %d\n", +						"%s SuperSpeed USB device number %d using %s\n",  						(udev->config) ? "reset" : "new", -						udev->bus->controller->driver->name, devnum); +						devnum, udev->bus->controller->driver->name);  			}  			/* cope with hardware quirkiness: @@ -2836,13 +4374,18 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  			 *  - read ep0 maxpacket even for high and low speed,  			 */  			msleep(10); -			if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) +			/* use_new_scheme() checks the speed which may have +			 * changed since the initial look so we cache the result +			 * in did_new_scheme +			 */ +			if (did_new_scheme)  				break; -  		} +		}  		retval = usb_get_device_descriptor(udev, 8);  		if (retval < 8) { -			dev_err(&udev->dev, +			if (retval != -ENODEV) +				dev_err(&udev->dev,  					"device descriptor read/8, error %d\n",  					retval);  			if (retval >= 0) @@ -2855,12 +4398,31 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	if (retval)  		goto fail; +	if (hcd->phy && !hdev->parent) +		usb_phy_notify_connect(hcd->phy, udev->speed); + +	/* +	 * Some superspeed devices have finished the link training process +	 * and attached to a superspeed hub port, but the device descriptor +	 * got from those devices show they aren't superspeed devices. Warm +	 * reset the port attached by the devices can fix them. +	 */ +	if ((udev->speed == USB_SPEED_SUPER) && +			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { +		dev_err(&udev->dev, "got a wrong device descriptor, " +				"warm reset device\n"); +		hub_port_reset(hub, port1, udev, +				HUB_BH_RESET_TIME, true); +		retval = -EINVAL; +		goto fail; +	} +  	if (udev->descriptor.bMaxPacketSize0 == 0xff ||  			udev->speed == USB_SPEED_SUPER)  		i = 512;  	else  		i = udev->descriptor.bMaxPacketSize0; -	if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { +	if (usb_endpoint_maxp(&udev->ep0.desc) != i) {  		if (udev->speed == USB_SPEED_LOW ||  				!(i == 8 || i == 16 || i == 32 || i == 64)) {  			dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); @@ -2874,26 +4436,36 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);  		usb_ep0_reinit(udev);  	} -   +  	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);  	if (retval < (signed)sizeof(udev->descriptor)) { -		dev_err(&udev->dev, "device descriptor read/all, error %d\n", -			retval); +		if (retval != -ENODEV) +			dev_err(&udev->dev, "device descriptor read/all, error %d\n", +					retval);  		if (retval >= 0)  			retval = -ENOMSG;  		goto fail;  	} +	if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { +		retval = usb_get_bos_descriptor(udev); +		if (!retval) { +			udev->lpm_capable = usb_device_supports_lpm(udev); +			usb_set_lpm_parameters(udev); +		} +	} +  	retval = 0;  	/* notify HCD that we have a device connected and addressed */  	if (hcd->driver->update_device)  		hcd->driver->update_device(hcd, udev); +	hub_set_initial_usb2_lpm_policy(udev);  fail:  	if (retval) {  		hub_port_disable(hub, port1, 0); -		update_address(udev, devnum);	/* for disconnect processing */ +		update_devnum(udev, devnum);	/* for disconnect processing */  	} -	mutex_unlock(&usb_address0_mutex); +	mutex_unlock(&hdev->bus->usb_address0_mutex);  	return retval;  } @@ -2915,7 +4487,8 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)  		/* hub LEDs are probably harder to miss than syslog */  		if (hub->has_indicators) {  			hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; -			schedule_delayed_work (&hub->leds, 0); +			queue_delayed_work(system_power_efficient_wq, +					&hub->leds, 0);  		}  	}  	kfree(qual); @@ -2933,101 +4506,58 @@ hub_power_remaining (struct usb_hub *hub)  	remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;  	for (port1 = 1; port1 <= hdev->maxchild; ++port1) { -		struct usb_device	*udev = hdev->children[port1 - 1]; -		int			delta; +		struct usb_port *port_dev = hub->ports[port1 - 1]; +		struct usb_device *udev = port_dev->child; +		unsigned unit_load; +		int delta;  		if (!udev)  			continue; +		if (hub_is_superspeed(udev)) +			unit_load = 150; +		else +			unit_load = 100; -		/* Unconfigured devices may not use more than 100mA, -		 * or 8mA for OTG ports */ +		/* +		 * Unconfigured devices may not use more than one unit load, +		 * or 8mA for OTG ports +		 */  		if (udev->actconfig) -			delta = udev->actconfig->desc.bMaxPower * 2; +			delta = usb_get_max_power(udev, udev->actconfig);  		else if (port1 != udev->bus->otg_port || hdev->parent) -			delta = 100; +			delta = unit_load;  		else  			delta = 8;  		if (delta > hub->mA_per_port) -			dev_warn(&udev->dev, -				 "%dmA is over %umA budget for port %d!\n", -				 delta, hub->mA_per_port, port1); +			dev_warn(&port_dev->dev, "%dmA is over %umA budget!\n", +					delta, hub->mA_per_port);  		remaining -= delta;  	}  	if (remaining < 0) {  		dev_warn(hub->intfdev, "%dmA over power budget!\n", -			- remaining); +			-remaining);  		remaining = 0;  	}  	return remaining;  } -/* Handle physical or logical connection change events. - * This routine is called when: - * 	a port connection-change occurs; - *	a port enable-change occurs (often caused by EMI); - *	usb_reset_and_verify_device() encounters changed descriptors (as from - *		a firmware download) - * caller already locked the hub - */ -static void hub_port_connect_change(struct usb_hub *hub, int port1, -					u16 portstatus, u16 portchange) +static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, +		u16 portchange)  { +	int status, i; +	unsigned unit_load;  	struct usb_device *hdev = hub->hdev; -	struct device *hub_dev = hub->intfdev;  	struct usb_hcd *hcd = bus_to_hcd(hdev->bus); -	unsigned wHubCharacteristics = -			le16_to_cpu(hub->descriptor->wHubCharacteristics); -	struct usb_device *udev; -	int status, i; - -	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); -		hub->indicator[port1-1] = INDICATOR_AUTO; -	} - -#ifdef	CONFIG_USB_OTG -	/* during HNP, don't repeat the debounce */ -	if (hdev->bus->is_b_host) -		portchange &= ~(USB_PORT_STAT_C_CONNECTION | -				USB_PORT_STAT_C_ENABLE); -#endif - -	/* Try to resuscitate an existing device */ -	udev = hdev->children[port1-1]; -	if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && -			udev->state != USB_STATE_NOTATTACHED) { -		usb_lock_device(udev); -		if (portstatus & USB_PORT_STAT_ENABLE) { -			status = 0;		/* Nothing to do */ - -#ifdef CONFIG_USB_SUSPEND -		} else if (udev->state == USB_STATE_SUSPENDED && -				udev->persist_enabled) { -			/* For a suspended device, treat this as a -			 * remote wakeup event. -			 */ -			status = usb_remote_wakeup(udev); -#endif - -		} else { -			status = -ENODEV;	/* Don't resuscitate */ -		} -		usb_unlock_device(udev); - -		if (status == 0) { -			clear_bit(port1, hub->change_bits); -			return; -		} -	} +	struct usb_port *port_dev = hub->ports[port1 - 1]; +	struct usb_device *udev = port_dev->child;  	/* Disconnect any existing devices under this port */ -	if (udev) -		usb_disconnect(&hdev->children[port1-1]); -	clear_bit(port1, hub->change_bits); +	if (udev) { +		if (hcd->phy && !hdev->parent && +				!(portstatus & USB_PORT_STAT_CONNECTION)) +			usb_phy_notify_disconnect(hcd->phy, udev->speed); +		usb_disconnect(&port_dev->child); +	}  	/* We can forget about a "removed" device when there's a physical  	 * disconnect or the connect status changes. @@ -3038,11 +4568,11 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  	if (portchange & (USB_PORT_STAT_C_CONNECTION |  				USB_PORT_STAT_C_ENABLE)) { -		status = hub_port_debounce(hub, port1); +		status = hub_port_debounce_be_stable(hub, port1);  		if (status < 0) { -			if (printk_ratelimit()) -				dev_err(hub_dev, "connect-debounce failed, " -						"port %d disabled\n", port1); +			if (status != -ENODEV && printk_ratelimit()) +				dev_err(&port_dev->dev, +						"connect-debounce failed\n");  			portstatus &= ~USB_PORT_STAT_CONNECTION;  		} else {  			portstatus = status; @@ -3056,15 +4586,20 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  			test_bit(port1, hub->removed_bits)) {  		/* maybe switch power back on (e.g. root hub was reset) */ -		if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 -				&& !(portstatus & USB_PORT_STAT_POWER)) +		if (hub_is_port_power_switchable(hub) +				&& !port_is_power_on(hub, portstatus))  			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);  		if (portstatus & USB_PORT_STAT_ENABLE) -  			goto done; +			goto done;  		return;  	} +	if (hub_is_superspeed(hub->hdev)) +		unit_load = 150; +	else +		unit_load = 100; +	status = 0;  	for (i = 0; i < SET_CONFIG_TRIES; i++) {  		/* reallocate for each attempt, since references @@ -3072,50 +4607,32 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  		 */  		udev = usb_alloc_dev(hdev, hdev->bus, port1);  		if (!udev) { -			dev_err (hub_dev, -				"couldn't allocate port %d usb_device\n", -				port1); +			dev_err(&port_dev->dev, +					"couldn't allocate usb_device\n");  			goto done;  		}  		usb_set_device_state(udev, USB_STATE_POWERED); - 		udev->bus_mA = hub->mA_per_port; +		udev->bus_mA = hub->mA_per_port;  		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; -		/* -		 * Set the address. -		 * Note xHCI needs to issue an address device command later -		 * in the hub_port_init sequence for SS/HS/FS/LS devices, -		 * and xHC will assign an address to the device. But use -		 * kernel assigned address here, to avoid any address conflict -		 * issue. -		 */ -		choose_address(udev); +		choose_devnum(udev);  		if (udev->devnum <= 0) {  			status = -ENOTCONN;	/* Don't retry */  			goto loop;  		}  		/* reset (non-USB 3.0 devices) and get descriptor */ +		usb_lock_port(port_dev);  		status = hub_port_init(hub, udev, port1, i); +		usb_unlock_port(port_dev);  		if (status < 0)  			goto loop; @@ -3130,16 +4647,15 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  		 * on the parent.  		 */  		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB -				&& udev->bus_mA <= 100) { +				&& udev->bus_mA <= unit_load) {  			u16	devstat;  			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,  					&devstat); -			if (status < 2) { +			if (status) {  				dev_dbg(&udev->dev, "get status %d ?\n", status);  				goto loop_disable;  			} -			le16_to_cpus(&devstat);  			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {  				dev_err(&udev->dev,  					"can't connect bus-powered hub " @@ -3147,13 +4663,15 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  				if (hub->has_indicators) {  					hub->indicator[port1-1] =  						INDICATOR_AMBER_BLINK; -					schedule_delayed_work (&hub->leds, 0); +					queue_delayed_work( +						system_power_efficient_wq, +						&hub->leds, 0);  				}  				status = -ENOTCONN;	/* Don't retry */  				goto loop_disable;  			}  		} -  +  		/* check for devices running slower than they could */  		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200  				&& udev->speed == USB_SPEED_FULL @@ -3166,6 +4684,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  		 */  		status = 0; +		mutex_lock(&usb_port_peer_mutex); +  		/* We mustn't add new devices if the parent hub has  		 * been disconnected; we would race with the  		 * recursively_mark_NOTATTACHED() routine. @@ -3174,16 +4694,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  		if (hdev->state == USB_STATE_NOTATTACHED)  			status = -ENOTCONN;  		else -			hdev->children[port1-1] = udev; +			port_dev->child = udev;  		spin_unlock_irq(&device_state_lock); +		mutex_unlock(&usb_port_peer_mutex);  		/* Run it through the hoops (find a driver, etc) */  		if (!status) {  			status = usb_new_device(udev);  			if (status) { +				mutex_lock(&usb_port_peer_mutex);  				spin_lock_irq(&device_state_lock); -				hdev->children[port1-1] = NULL; +				port_dev->child = NULL;  				spin_unlock_irq(&device_state_lock); +				mutex_unlock(&usb_port_peer_mutex);  			}  		} @@ -3192,7 +4715,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,  		status = hub_power_remaining(hub);  		if (status) -			dev_dbg(hub_dev, "%dmA power budget left\n", status); +			dev_dbg(hub->intfdev, "%dmA power budget left\n", status);  		return; @@ -3200,7 +4723,7 @@ loop_disable:  		hub_port_disable(hub, port1, 1);  loop:  		usb_ep0_reinit(udev); -		release_address(udev); +		release_devnum(udev);  		hub_free_dev(udev);  		usb_put_dev(udev);  		if ((status == -ENOTCONN) || (status == -ENOTSUPP)) @@ -3208,16 +4731,202 @@ loop:  	}  	if (hub->hdev->parent ||  			!hcd->driver->port_handed_over || -			!(hcd->driver->port_handed_over)(hcd, port1)) -		dev_err(hub_dev, "unable to enumerate USB device on port %d\n", -				port1); -  +			!(hcd->driver->port_handed_over)(hcd, port1)) { +		if (status != -ENOTCONN && status != -ENODEV) +			dev_err(&port_dev->dev, +					"unable to enumerate USB device\n"); +	} +  done:  	hub_port_disable(hub, port1, 1);  	if (hcd->driver->relinquish_port && !hub->hdev->parent)  		hcd->driver->relinquish_port(hcd, port1); + +} + +/* Handle physical or logical connection change events. + * This routine is called when: + *	a port connection-change occurs; + *	a port enable-change occurs (often caused by EMI); + *	usb_reset_and_verify_device() encounters changed descriptors (as from + *		a firmware download) + * caller already locked the hub + */ +static void hub_port_connect_change(struct usb_hub *hub, int port1, +					u16 portstatus, u16 portchange) +		__must_hold(&port_dev->status_lock) +{ +	struct usb_port *port_dev = hub->ports[port1 - 1]; +	struct usb_device *udev = port_dev->child; +	int status = -ENODEV; + +	dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus, +			portchange, portspeed(hub, portstatus)); + +	if (hub->has_indicators) { +		set_port_led(hub, port1, HUB_LED_AUTO); +		hub->indicator[port1-1] = INDICATOR_AUTO; +	} + +#ifdef	CONFIG_USB_OTG +	/* during HNP, don't repeat the debounce */ +	if (hub->hdev->bus->is_b_host) +		portchange &= ~(USB_PORT_STAT_C_CONNECTION | +				USB_PORT_STAT_C_ENABLE); +#endif + +	/* Try to resuscitate an existing device */ +	if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && +			udev->state != USB_STATE_NOTATTACHED) { +		if (portstatus & USB_PORT_STAT_ENABLE) { +			status = 0;		/* Nothing to do */ +#ifdef CONFIG_PM_RUNTIME +		} else if (udev->state == USB_STATE_SUSPENDED && +				udev->persist_enabled) { +			/* For a suspended device, treat this as a +			 * remote wakeup event. +			 */ +			usb_unlock_port(port_dev); +			status = usb_remote_wakeup(udev); +			usb_lock_port(port_dev); +#endif +		} else { +			/* Don't resuscitate */; +		} +	} +	clear_bit(port1, hub->change_bits); + +	/* successfully revalidated the connection */ +	if (status == 0) +		return; + +	usb_unlock_port(port_dev); +	hub_port_connect(hub, port1, portstatus, portchange); +	usb_lock_port(port_dev); +} + +static void port_event(struct usb_hub *hub, int port1) +		__must_hold(&port_dev->status_lock) +{ +	int connect_change, reset_device = 0; +	struct usb_port *port_dev = hub->ports[port1 - 1]; +	struct usb_device *udev = port_dev->child; +	struct usb_device *hdev = hub->hdev; +	u16 portstatus, portchange; + +	connect_change = test_bit(port1, hub->change_bits); +	clear_bit(port1, hub->event_bits); +	clear_bit(port1, hub->wakeup_bits); + +	if (hub_port_status(hub, port1, &portstatus, &portchange) < 0) +		return; + +	if (portchange & USB_PORT_STAT_C_CONNECTION) { +		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); +		connect_change = 1; +	} + +	if (portchange & USB_PORT_STAT_C_ENABLE) { +		if (!connect_change) +			dev_dbg(&port_dev->dev, "enable change, status %08x\n", +					portstatus); +		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); + +		/* +		 * EM interference sometimes causes badly shielded USB devices +		 * to be shutdown by the hub, this hack enables them again. +		 * Works at least with mouse driver. +		 */ +		if (!(portstatus & USB_PORT_STAT_ENABLE) +		    && !connect_change && udev) { +			dev_err(&port_dev->dev, "disabled by hub (EMI?), re-enabling...\n"); +			connect_change = 1; +		} +	} + +	if (portchange & USB_PORT_STAT_C_OVERCURRENT) { +		u16 status = 0, unused; + +		dev_dbg(&port_dev->dev, "over-current change\n"); +		usb_clear_port_feature(hdev, port1, +				USB_PORT_FEAT_C_OVER_CURRENT); +		msleep(100);	/* Cool down */ +		hub_power_on(hub, true); +		hub_port_status(hub, port1, &status, &unused); +		if (status & USB_PORT_STAT_OVERCURRENT) +			dev_err(&port_dev->dev, "over-current condition\n"); +	} + +	if (portchange & USB_PORT_STAT_C_RESET) { +		dev_dbg(&port_dev->dev, "reset change\n"); +		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_RESET); +	} +	if ((portchange & USB_PORT_STAT_C_BH_RESET) +	    && hub_is_superspeed(hdev)) { +		dev_dbg(&port_dev->dev, "warm reset change\n"); +		usb_clear_port_feature(hdev, port1, +				USB_PORT_FEAT_C_BH_PORT_RESET); +	} +	if (portchange & USB_PORT_STAT_C_LINK_STATE) { +		dev_dbg(&port_dev->dev, "link state change\n"); +		usb_clear_port_feature(hdev, port1, +				USB_PORT_FEAT_C_PORT_LINK_STATE); +	} +	if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) { +		dev_warn(&port_dev->dev, "config error\n"); +		usb_clear_port_feature(hdev, port1, +				USB_PORT_FEAT_C_PORT_CONFIG_ERROR); +	} + +	/* skip port actions that require the port to be powered on */ +	if (!pm_runtime_active(&port_dev->dev)) +		return; + +	if (hub_handle_remote_wakeup(hub, port1, portstatus, portchange)) +		connect_change = 1; + +	/* +	 * Warm reset a USB3 protocol port if it's in +	 * SS.Inactive state. +	 */ +	if (hub_port_warm_reset_required(hub, portstatus)) { +		dev_dbg(&port_dev->dev, "do warm reset\n"); +		if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) +				|| udev->state == USB_STATE_NOTATTACHED) { +			if (hub_port_reset(hub, port1, NULL, +					HUB_BH_RESET_TIME, true) < 0) +				hub_port_disable(hub, port1, 1); +		} else +			reset_device = 1; +	} + +	/* +	 * On disconnect USB3 protocol ports transit from U0 to +	 * SS.Inactive to Rx.Detect. If this happens a warm- +	 * reset is not needed, but a (re)connect may happen +	 * before khubd runs and sees the disconnect, and the +	 * device may be an unknown state. +	 * +	 * If the port went through SS.Inactive without khubd +	 * seeing it the C_LINK_STATE change flag will be set, +	 * and we reset the dev to put it in a known state. +	 */ +	if (reset_device || (udev && hub_is_superspeed(hub->hdev) +				&& (portchange & USB_PORT_STAT_C_LINK_STATE) +				&& (portstatus & USB_PORT_STAT_CONNECTION))) { +		usb_unlock_port(port_dev); +		usb_lock_device(udev); +		usb_reset_device(udev); +		usb_unlock_device(udev); +		usb_lock_port(port_dev); +		connect_change = 0; +	} + +	if (connect_change) +		hub_port_connect_change(hub, port1, portstatus, portchange);  } +  static void hub_events(void)  {  	struct list_head *tmp; @@ -3227,10 +4936,7 @@ static void hub_events(void)  	struct device *hub_dev;  	u16 hubstatus;  	u16 hubchange; -	u16 portstatus; -	u16 portchange;  	int i, ret; -	int connect_change;  	/*  	 *  We restart the list every time to avoid a deadlock with @@ -3258,9 +4964,7 @@ static void hub_events(void)  		hub_dev = hub->intfdev;  		intf = to_usb_interface(hub_dev);  		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", -				hdev->state, hub->descriptor -					? hub->descriptor->bNbrPorts -					: 0, +				hdev->state, hdev->maxchild,  				/* NOTE: expects max 15 ports... */  				(u16) hub->change_bits[0],  				(u16) hub->event_bits[0]); @@ -3305,98 +5009,29 @@ static void hub_events(void)  		}  		/* deal with port status changes */ -		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) { -			if (test_bit(i, hub->busy_bits)) -				continue; -			connect_change = test_bit(i, hub->change_bits); -			if (!test_and_clear_bit(i, hub->event_bits) && -					!connect_change) -				continue; - -			ret = hub_port_status(hub, i, -					&portstatus, &portchange); -			if (ret < 0) -				continue; - -			if (portchange & USB_PORT_STAT_C_CONNECTION) { -				clear_port_feature(hdev, i, -					USB_PORT_FEAT_C_CONNECTION); -				connect_change = 1; -			} - -			if (portchange & USB_PORT_STAT_C_ENABLE) { -				if (!connect_change) -					dev_dbg (hub_dev, -						"port %d enable change, " -						"status %08x\n", -						i, portstatus); -				clear_port_feature(hdev, i, -					USB_PORT_FEAT_C_ENABLE); +		for (i = 1; i <= hdev->maxchild; i++) { +			struct usb_port *port_dev = hub->ports[i - 1]; +			if (test_bit(i, hub->event_bits) +					|| test_bit(i, hub->change_bits) +					|| test_bit(i, hub->wakeup_bits)) {  				/* -				 * EM interference sometimes causes badly -				 * shielded USB devices to be shutdown by -				 * the hub, this hack enables them again. -				 * Works at least with mouse driver.  +				 * The get_noresume and barrier ensure that if +				 * the port was in the process of resuming, we +				 * flush that work and keep the port active for +				 * the duration of the port_event().  However, +				 * if the port is runtime pm suspended +				 * (powered-off), we leave it in that state, run +				 * an abbreviated port_event(), and move on.  				 */ -				if (!(portstatus & USB_PORT_STAT_ENABLE) -				    && !connect_change -				    && hdev->children[i-1]) { -					dev_err (hub_dev, -					    "port %i " -					    "disabled by hub (EMI?), " -					    "re-enabling...\n", -						i); -					connect_change = 1; -				} -			} - -			if (portchange & USB_PORT_STAT_C_SUSPEND) { -				struct usb_device *udev; - -				clear_port_feature(hdev, i, -					USB_PORT_FEAT_C_SUSPEND); -				udev = hdev->children[i-1]; -				if (udev) { -					/* TRSMRCY = 10 msec */ -					msleep(10); - -					usb_lock_device(udev); -					ret = usb_remote_wakeup(hdev-> -							children[i-1]); -					usb_unlock_device(udev); -					if (ret < 0) -						connect_change = 1; -				} else { -					ret = -ENODEV; -					hub_port_disable(hub, i, 1); -				} -				dev_dbg (hub_dev, -					"resume on port %d, status %d\n", -					i, ret); -			} -			 -			if (portchange & USB_PORT_STAT_C_OVERCURRENT) { -				dev_err (hub_dev, -					"over-current change on port %d\n", -					i); -				clear_port_feature(hdev, i, -					USB_PORT_FEAT_C_OVER_CURRENT); -				hub_power_on(hub, true); -			} - -			if (portchange & USB_PORT_STAT_C_RESET) { -				dev_dbg (hub_dev, -					"reset change on port %d\n", -					i); -				clear_port_feature(hdev, i, -					USB_PORT_FEAT_C_RESET); +				pm_runtime_get_noresume(&port_dev->dev); +				pm_runtime_barrier(&port_dev->dev); +				usb_lock_port(port_dev); +				port_event(hub, i); +				usb_unlock_port(port_dev); +				pm_runtime_put_sync(&port_dev->dev);  			} - -			if (connect_change) -				hub_port_connect_change(hub, i, -						portstatus, portchange); -		} /* end for i */ +		}  		/* deal with hub status changes */  		if (test_and_clear_bit(0, hub->event_bits) == 0) @@ -3414,10 +5049,17 @@ static void hub_events(void)  					hub->limited_power = 0;  			}  			if (hubchange & HUB_CHANGE_OVERCURRENT) { -				dev_dbg (hub_dev, "overcurrent change\n"); -				msleep(500);	/* Cool down */ +				u16 status = 0; +				u16 unused; + +				dev_dbg(hub_dev, "over-current change\n");  				clear_hub_feature(hdev, C_HUB_OVER_CURRENT); -                        	hub_power_on(hub, true); +				msleep(500);	/* Cool down */ +				hub_power_on(hub, true); +				hub_hub_status(hub, &status, &unused); +				if (status & HUB_STATUS_OVERCURRENT) +					dev_err(hub_dev, "over-current " +						"condition\n");  			}  		} @@ -3433,12 +5075,12 @@ static void hub_events(void)  		usb_unlock_device(hdev);  		kref_put(&hub->kref, hub_release); -        } /* end while (1) */ +	} /* end while (1) */  }  static int hub_thread(void *__unused)  { -	/* khubd needs to be freezable to avoid intefering with USB-PERSIST +	/* khubd needs to be freezable to avoid interfering with USB-PERSIST  	 * port handover.  Otherwise it might see that a full-speed device  	 * was gone before the EHCI controller had handed its port over to  	 * the companion full-speed controller. @@ -3457,6 +5099,11 @@ static int hub_thread(void *__unused)  }  static const struct usb_device_id hub_id_table[] = { +    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR +			| USB_DEVICE_ID_MATCH_INT_CLASS, +      .idVendor = USB_VENDOR_GENESYS_LOGIC, +      .bInterfaceClass = USB_CLASS_HUB, +      .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},      { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,        .bDeviceClass = USB_CLASS_HUB},      { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, @@ -3514,7 +5161,8 @@ void usb_hub_cleanup(void)  } /* usb_hub_cleanup() */  static int descriptors_changed(struct usb_device *udev, -		struct usb_device_descriptor *old_device_descriptor) +		struct usb_device_descriptor *old_device_descriptor, +		struct usb_host_bos *old_bos)  {  	int		changed = 0;  	unsigned	index; @@ -3528,6 +5176,16 @@ static int descriptors_changed(struct usb_device *udev,  			sizeof(*old_device_descriptor)) != 0)  		return 1; +	if ((old_bos && !udev->bos) || (!old_bos && udev->bos)) +		return 1; +	if (udev->bos) { +		len = le16_to_cpu(udev->bos->desc->wTotalLength); +		if (len != le16_to_cpu(old_bos->desc->wTotalLength)) +			return 1; +		if (memcmp(udev->bos->desc, old_bos->desc, len)) +			return 1; +	} +  	/* Since the idVendor, idProduct, and bcdDevice values in the  	 * device descriptor haven't changed, we will assume the  	 * Manufacturer and Product strings haven't changed either. @@ -3603,19 +5261,23 @@ static int descriptors_changed(struct usb_device *udev,   * re-connected.  All drivers will be unbound, and the device will be   * re-enumerated and probed all over again.   * - * Returns 0 if the reset succeeded, -ENODEV if the device has been + * Return: 0 if the reset succeeded, -ENODEV if the device has been   * flagged for logical disconnection, or some other negative error code   * if the reset wasn't even attempted.   * - * The caller must own the device lock.  For example, it's safe to use - * this from a driver probe() routine after downloading new firmware. - * For calls that might not occur during probe(), drivers should lock - * the device using usb_lock_device_for_reset(). + * Note: + * The caller must own the device lock and the port lock, the latter is + * taken by usb_reset_device().  For example, it's safe to use + * usb_reset_device() from a driver probe() routine after downloading + * new firmware.  For calls that might not occur during probe(), drivers + * should lock the device using usb_lock_device_for_reset().   *   * Locking exception: This routine may also be called from within an   * autoresume handler.  Such usage won't conflict with other tasks   * holding the device lock because these tasks should always call - * usb_autopm_resume_device(), thereby preventing any unwanted autoresume. + * usb_autopm_resume_device(), thereby preventing any unwanted + * autoresume.  The autoresume handler is expected to have already + * acquired the port lock before calling this routine.   */  static int usb_reset_and_verify_device(struct usb_device *udev)  { @@ -3623,7 +5285,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  	struct usb_hub			*parent_hub;  	struct usb_hcd			*hcd = bus_to_hcd(udev->bus);  	struct usb_device_descriptor	descriptor = udev->descriptor; -	int 				i, ret = 0; +	struct usb_host_bos		*bos; +	int				i, j, ret = 0;  	int				port1 = udev->portnum;  	if (udev->state == USB_STATE_NOTATTACHED || @@ -3633,14 +5296,37 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  		return -EINVAL;  	} -	if (!parent_hdev) { -		/* this requires hcd-specific logic; see ohci_restart() */ -		dev_dbg(&udev->dev, "%s for root hub!\n", __func__); +	if (!parent_hdev)  		return -EISDIR; + +	parent_hub = usb_hub_to_struct_hub(parent_hdev); + +	/* Disable USB2 hardware LPM. +	 * It will be re-enabled by the enumeration process. +	 */ +	if (udev->usb2_hw_lpm_enabled == 1) +		usb_set_usb2_hardware_lpm(udev, 0); + +	bos = udev->bos; +	udev->bos = NULL; + +	/* Disable LPM and LTM while we reset the device and reinstall the alt +	 * settings.  Device-initiated LPM settings, and system exit latency +	 * settings are cleared when the device is reset, so we have to set +	 * them up again. +	 */ +	ret = usb_unlocked_disable_lpm(udev); +	if (ret) { +		dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__); +		goto re_enumerate; +	} +	ret = usb_disable_ltm(udev); +	if (ret) { +		dev_err(&udev->dev, "%s Failed to disable LTM\n.", +				__func__); +		goto re_enumerate;  	} -	parent_hub = hdev_to_hub(parent_hdev); -	set_bit(port1, parent_hub->busy_bits);  	for (i = 0; i < SET_CONFIG_TRIES; ++i) {  		/* ep0 maxpacket size may change; let the HCD know about it. @@ -3650,29 +5336,28 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  		if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)  			break;  	} -	clear_bit(port1, parent_hub->busy_bits);  	if (ret < 0)  		goto re_enumerate; -  +  	/* Device might have changed firmware (DFU or similar) */ -	if (descriptors_changed(udev, &descriptor)) { +	if (descriptors_changed(udev, &descriptor, bos)) {  		dev_info(&udev->dev, "device firmware changed\n");  		udev->descriptor = descriptor;	/* for disconnect() calls */  		goto re_enumerate; -  	} +	}  	/* Restore the device's previous configuration */  	if (!udev->actconfig)  		goto done; -	mutex_lock(&hcd->bandwidth_mutex); +	mutex_lock(hcd->bandwidth_mutex);  	ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);  	if (ret < 0) {  		dev_warn(&udev->dev,  				"Busted HC?  Not enough HCD resources for "  				"old configuration.\n"); -		mutex_unlock(&hcd->bandwidth_mutex); +		mutex_unlock(hcd->bandwidth_mutex);  		goto re_enumerate;  	}  	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), @@ -3683,10 +5368,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  		dev_err(&udev->dev,  			"can't restore configuration #%d (error=%d)\n",  			udev->actconfig->desc.bConfigurationValue, ret); -		mutex_unlock(&hcd->bandwidth_mutex); +		mutex_unlock(hcd->bandwidth_mutex);  		goto re_enumerate; -  	} -	mutex_unlock(&hcd->bandwidth_mutex); +	} +	mutex_unlock(hcd->bandwidth_mutex);  	usb_set_device_state(udev, USB_STATE_CONFIGURED);  	/* Put interfaces back into the same altsettings as before. @@ -3723,13 +5408,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  				ret);  			goto re_enumerate;  		} +		/* Resetting also frees any allocated streams */ +		for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) +			intf->cur_altsetting->endpoint[j].streams = 0;  	}  done: +	/* Now that the alt settings are re-installed, enable LTM and LPM. */ +	usb_set_usb2_hardware_lpm(udev, 1); +	usb_unlocked_enable_lpm(udev); +	usb_enable_ltm(udev); +	usb_release_bos_descriptor(udev); +	udev->bos = bos;  	return 0; -  +  re_enumerate: +	/* LPM state doesn't matter when we're about to destroy the device. */  	hub_port_logical_disconnect(parent_hub, port1); +	usb_release_bos_descriptor(udev); +	udev->bos = bos;  	return -ENODEV;  } @@ -3741,8 +5438,9 @@ re_enumerate:   * method), performs the port reset, and then lets the drivers know that   * the reset is over (using their post_reset method).   * - * Return value is the same as for usb_reset_and_verify_device(). + * Return: The same as for usb_reset_and_verify_device().   * + * Note:   * The caller must own the device lock.  For example, it's safe to use   * this from a driver probe() routine after downloading new firmware.   * For calls that might not occur during probe(), drivers should lock @@ -3757,7 +5455,10 @@ int usb_reset_device(struct usb_device *udev)  {  	int ret;  	int i; +	unsigned int noio_flag; +	struct usb_port *port_dev;  	struct usb_host_config *config = udev->actconfig; +	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);  	if (udev->state == USB_STATE_NOTATTACHED ||  			udev->state == USB_STATE_SUSPENDED) { @@ -3766,6 +5467,25 @@ int usb_reset_device(struct usb_device *udev)  		return -EINVAL;  	} +	if (!udev->parent) { +		/* this requires hcd-specific logic; see ohci_restart() */ +		dev_dbg(&udev->dev, "%s for root hub!\n", __func__); +		return -EISDIR; +	} + +	port_dev = hub->ports[udev->portnum - 1]; + +	/* +	 * Don't allocate memory with GFP_KERNEL in current +	 * context to avoid possible deadlock if usb mass +	 * storage interface or usbnet interface(iSCSI case) +	 * is included in current configuration. The easist +	 * approach is to do it for every device reset, +	 * because the device 'memalloc_noio' flag may have +	 * not been set before reseting the usb device. +	 */ +	noio_flag = memalloc_noio_save(); +  	/* Prevent autosuspend during the reset */  	usb_autoresume_device(udev); @@ -3788,7 +5508,9 @@ int usb_reset_device(struct usb_device *udev)  		}  	} +	usb_lock_port(port_dev);  	ret = usb_reset_and_verify_device(udev); +	usb_unlock_port(port_dev);  	if (config) {  		for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { @@ -3803,13 +5525,15 @@ int usb_reset_device(struct usb_device *udev)  				else if (cintf->condition ==  						USB_INTERFACE_BOUND)  					rebind = 1; +				if (rebind) +					cintf->needs_binding = 1;  			} -			if (ret == 0 && rebind) -				usb_rebind_intf(cintf);  		} +		usb_unbind_and_rebind_marked_interfaces(udev);  	}  	usb_autosuspend_device(udev); +	memalloc_noio_restore(noio_flag);  	return ret;  }  EXPORT_SYMBOL_GPL(usb_reset_device); @@ -3856,3 +5580,93 @@ void usb_queue_reset_device(struct usb_interface *iface)  	schedule_work(&iface->reset_ws);  }  EXPORT_SYMBOL_GPL(usb_queue_reset_device); + +/** + * usb_hub_find_child - Get the pointer of child device + * attached to the port which is specified by @port1. + * @hdev: USB device belonging to the usb hub + * @port1: port num to indicate which port the child device + *	is attached to. + * + * USB drivers call this function to get hub's child device + * pointer. + * + * Return: %NULL if input param is invalid and + * child's usb_device pointer if non-NULL. + */ +struct usb_device *usb_hub_find_child(struct usb_device *hdev, +		int port1) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); + +	if (port1 < 1 || port1 > hdev->maxchild) +		return NULL; +	return hub->ports[port1 - 1]->child; +} +EXPORT_SYMBOL_GPL(usb_hub_find_child); + +void usb_hub_adjust_deviceremovable(struct usb_device *hdev, +		struct usb_hub_descriptor *desc) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); +	enum usb_port_connect_type connect_type; +	int i; + +	if (!hub) +		return; + +	if (!hub_is_superspeed(hdev)) { +		for (i = 1; i <= hdev->maxchild; i++) { +			struct usb_port *port_dev = hub->ports[i - 1]; + +			connect_type = port_dev->connect_type; +			if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { +				u8 mask = 1 << (i%8); + +				if (!(desc->u.hs.DeviceRemovable[i/8] & mask)) { +					dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n"); +					desc->u.hs.DeviceRemovable[i/8]	|= mask; +				} +			} +		} +	} else { +		u16 port_removable = le16_to_cpu(desc->u.ss.DeviceRemovable); + +		for (i = 1; i <= hdev->maxchild; i++) { +			struct usb_port *port_dev = hub->ports[i - 1]; + +			connect_type = port_dev->connect_type; +			if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { +				u16 mask = 1 << i; + +				if (!(port_removable & mask)) { +					dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n"); +					port_removable |= mask; +				} +			} +		} + +		desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); +	} +} + +#ifdef CONFIG_ACPI +/** + * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle + * @hdev: USB device belonging to the usb hub + * @port1: port num of the port + * + * Return: Port's acpi handle if successful, %NULL if params are + * invalid. + */ +acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, +	int port1) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); + +	if (!hub) +		return NULL; + +	return ACPI_HANDLE(&hub->ports[port1 - 1]->dev); +} +#endif diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h new file mode 100644 index 00000000000..326308e5396 --- /dev/null +++ b/drivers/usb/core/hub.h @@ -0,0 +1,156 @@ +/* + * usb hub driver head file + * + * Copyright (C) 1999 Linus Torvalds + * Copyright (C) 1999 Johannes Erdfelt + * Copyright (C) 1999 Gregory P. Smith + * Copyright (C) 2001 Brad Hards (bhards@bigpond.net.au) + * Copyright (C) 2012 Intel Corp (tianyu.lan@intel.com) + * + *  move struct usb_hub to this file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License + * for more details. + */ + +#include <linux/usb.h> +#include <linux/usb/ch11.h> +#include <linux/usb/hcd.h> +#include "usb.h" + +struct usb_hub { +	struct device		*intfdev;	/* the "interface" device */ +	struct usb_device	*hdev; +	struct kref		kref; +	struct urb		*urb;		/* for interrupt polling pipe */ + +	/* buffer for urb ... with extra space in case of babble */ +	u8			(*buffer)[8]; +	union { +		struct usb_hub_status	hub; +		struct usb_port_status	port; +	}			*status;	/* buffer for status reports */ +	struct mutex		status_mutex;	/* for the status buffer */ + +	int			error;		/* last reported error */ +	int			nerrors;	/* track consecutive errors */ + +	struct list_head	event_list;	/* hubs w/data or errs ready */ +	unsigned long		event_bits[1];	/* status change bitmask */ +	unsigned long		change_bits[1];	/* ports with logical connect +							status change */ +	unsigned long		removed_bits[1]; /* ports with a "removed" +							device present */ +	unsigned long		wakeup_bits[1];	/* ports that have signaled +							remote wakeup */ +	unsigned long		power_bits[1]; /* ports that are powered */ +	unsigned long		child_usage_bits[1]; /* ports powered on for +							children */ +#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ +#error event_bits[] is too short! +#endif + +	struct usb_hub_descriptor *descriptor;	/* class descriptor */ +	struct usb_tt		tt;		/* Transaction Translator */ + +	unsigned		mA_per_port;	/* current for each child */ +#ifdef	CONFIG_PM +	unsigned		wakeup_enabled_descendants; +#endif + +	unsigned		limited_power:1; +	unsigned		quiescing:1; +	unsigned		disconnected:1; +	unsigned		in_reset:1; + +	unsigned		quirk_check_port_auto_suspend:1; + +	unsigned		has_indicators:1; +	u8			indicator[USB_MAXCHILDREN]; +	struct delayed_work	leds; +	struct delayed_work	init_work; +	struct usb_port		**ports; +}; + +/** + * struct usb port - kernel's representation of a usb port + * @child: usb device attached to the port + * @dev: generic device interface + * @port_owner: port's owner + * @peer: related usb2 and usb3 ports (share the same connector) + * @req: default pm qos request for hubs without port power control + * @connect_type: port's connect type + * @location: opaque representation of platform connector location + * @status_lock: synchronize port_event() vs usb_port_{suspend|resume} + * @portnum: port index num based one + * @is_superspeed cache super-speed status + */ +struct usb_port { +	struct usb_device *child; +	struct device dev; +	struct usb_dev_state *port_owner; +	struct usb_port *peer; +	struct dev_pm_qos_request *req; +	enum usb_port_connect_type connect_type; +	usb_port_location_t location; +	struct mutex status_lock; +	u8 portnum; +	unsigned int is_superspeed:1; +}; + +#define to_usb_port(_dev) \ +	container_of(_dev, struct usb_port, dev) + +extern int usb_hub_create_port_device(struct usb_hub *hub, +		int port1); +extern void usb_hub_remove_port_device(struct usb_hub *hub, +		int port1); +extern int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, +		int port1, bool set); +extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); +extern int hub_port_debounce(struct usb_hub *hub, int port1, +		bool must_be_connected); +extern int usb_clear_port_feature(struct usb_device *hdev, +		int port1, int feature); + +static inline bool hub_is_port_power_switchable(struct usb_hub *hub) +{ +	__le16 hcs; + +	if (!hub) +		return false; +	hcs = hub->descriptor->wHubCharacteristics; +	return (le16_to_cpu(hcs) & HUB_CHAR_LPSM) < HUB_CHAR_NO_LPSM; +} + +static inline int hub_is_superspeed(struct usb_device *hdev) +{ +	return hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS; +} + +static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) +{ +	unsigned delay = hub->descriptor->bPwrOn2PwrGood * 2; + +	/* Wait at least 100 msec for power to become stable */ +	return max(delay, 100U); +} + +static inline int hub_port_debounce_be_connected(struct usb_hub *hub, +		int port1) +{ +	return hub_port_debounce(hub, port1, true); +} + +static inline int hub_port_debounce_be_stable(struct usb_hub *hub, +		int port1) +{ +	return hub_port_debounce(hub, port1, false); +} + diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c deleted file mode 100644 index 9819a4cc3b2..00000000000 --- a/drivers/usb/core/inode.c +++ /dev/null @@ -1,776 +0,0 @@ -/*****************************************************************************/ - -/* - *	inode.c  --  Inode/Dentry functions for the USB device file system. - * - *	Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) - *	Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com) - * - *	This program is free software; you can redistribute it and/or modify - *	it under the terms of the GNU General Public License as published by - *	the Free Software Foundation; either version 2 of the License, or - *	(at your option) any later version. - * - *	This program is distributed in the hope that it will be useful, - *	but WITHOUT ANY WARRANTY; without even the implied warranty of - *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *	GNU General Public License for more details. - * - *	You should have received a copy of the GNU General Public License - *	along with this program; if not, write to the Free Software - *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - *  History: - *   0.1  04.01.2000  Created - *   0.2  10.12.2001  converted to use the vfs layer better - */ - -/*****************************************************************************/ - -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/mount.h> -#include <linux/pagemap.h> -#include <linux/init.h> -#include <linux/proc_fs.h> -#include <linux/usb.h> -#include <linux/namei.h> -#include <linux/usbdevice_fs.h> -#include <linux/parser.h> -#include <linux/notifier.h> -#include <linux/seq_file.h> -#include <linux/smp_lock.h> -#include <linux/usb/hcd.h> -#include <asm/byteorder.h> -#include "usb.h" - -#define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO) -#define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO) -#define USBFS_DEFAULT_LISTMODE S_IRUGO - -static const struct file_operations default_file_operations; -static struct vfsmount *usbfs_mount; -static int usbfs_mount_count;	/* = 0 */ -static int ignore_mount = 0; - -static struct dentry *devices_usbfs_dentry; -static int num_buses;	/* = 0 */ - -static uid_t devuid;	/* = 0 */ -static uid_t busuid;	/* = 0 */ -static uid_t listuid;	/* = 0 */ -static gid_t devgid;	/* = 0 */ -static gid_t busgid;	/* = 0 */ -static gid_t listgid;	/* = 0 */ -static umode_t devmode = USBFS_DEFAULT_DEVMODE; -static umode_t busmode = USBFS_DEFAULT_BUSMODE; -static umode_t listmode = USBFS_DEFAULT_LISTMODE; - -static int usbfs_show_options(struct seq_file *seq, struct vfsmount *mnt) -{ -	if (devuid != 0) -		seq_printf(seq, ",devuid=%u", devuid); -	if (devgid != 0) -		seq_printf(seq, ",devgid=%u", devgid); -	if (devmode != USBFS_DEFAULT_DEVMODE) -		seq_printf(seq, ",devmode=%o", devmode); -	if (busuid != 0) -		seq_printf(seq, ",busuid=%u", busuid); -	if (busgid != 0) -		seq_printf(seq, ",busgid=%u", busgid); -	if (busmode != USBFS_DEFAULT_BUSMODE) -		seq_printf(seq, ",busmode=%o", busmode); -	if (listuid != 0) -		seq_printf(seq, ",listuid=%u", listuid); -	if (listgid != 0) -		seq_printf(seq, ",listgid=%u", listgid); -	if (listmode != USBFS_DEFAULT_LISTMODE) -		seq_printf(seq, ",listmode=%o", listmode); - -	return 0; -} - -enum { -	Opt_devuid, Opt_devgid, Opt_devmode, -	Opt_busuid, Opt_busgid, Opt_busmode, -	Opt_listuid, Opt_listgid, Opt_listmode, -	Opt_err, -}; - -static const match_table_t tokens = { -	{Opt_devuid, "devuid=%u"}, -	{Opt_devgid, "devgid=%u"}, -	{Opt_devmode, "devmode=%o"}, -	{Opt_busuid, "busuid=%u"}, -	{Opt_busgid, "busgid=%u"}, -	{Opt_busmode, "busmode=%o"}, -	{Opt_listuid, "listuid=%u"}, -	{Opt_listgid, "listgid=%u"}, -	{Opt_listmode, "listmode=%o"}, -	{Opt_err, NULL} -}; - -static int parse_options(struct super_block *s, char *data) -{ -	char *p; -	int option; - -	/* (re)set to defaults. */ -	devuid = 0; -	busuid = 0; -	listuid = 0; -	devgid = 0; -	busgid = 0; -	listgid = 0; -	devmode = USBFS_DEFAULT_DEVMODE; -	busmode = USBFS_DEFAULT_BUSMODE; -	listmode = USBFS_DEFAULT_LISTMODE; - -	while ((p = strsep(&data, ",")) != NULL) { -		substring_t args[MAX_OPT_ARGS]; -		int token; -		if (!*p) -			continue; - -		token = match_token(p, tokens, args); -		switch (token) { -		case Opt_devuid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			devuid = option; -			break; -		case Opt_devgid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			devgid = option; -			break; -		case Opt_devmode: -			if (match_octal(&args[0], &option)) -				return -EINVAL; -			devmode = option & S_IRWXUGO; -			break; -		case Opt_busuid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			busuid = option; -			break; -		case Opt_busgid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			busgid = option; -			break; -		case Opt_busmode: -			if (match_octal(&args[0], &option)) -				return -EINVAL; -			busmode = option & S_IRWXUGO; -			break; -		case Opt_listuid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			listuid = option; -			break; -		case Opt_listgid: -			if (match_int(&args[0], &option)) -			       return -EINVAL; -			listgid = option; -			break; -		case Opt_listmode: -			if (match_octal(&args[0], &option)) -				return -EINVAL; -			listmode = option & S_IRWXUGO; -			break; -		default: -			printk(KERN_ERR "usbfs: unrecognised mount option " -			       "\"%s\" or missing value\n", p); -			return -EINVAL; -		} -	} - -	return 0; -} - -static void update_special(struct dentry *special) -{ -	special->d_inode->i_uid = listuid; -	special->d_inode->i_gid = listgid; -	special->d_inode->i_mode = S_IFREG | listmode; -} - -static void update_dev(struct dentry *dev) -{ -	dev->d_inode->i_uid = devuid; -	dev->d_inode->i_gid = devgid; -	dev->d_inode->i_mode = S_IFREG | devmode; -} - -static void update_bus(struct dentry *bus) -{ -	struct dentry *dev = NULL; - -	bus->d_inode->i_uid = busuid; -	bus->d_inode->i_gid = busgid; -	bus->d_inode->i_mode = S_IFDIR | busmode; - -	mutex_lock(&bus->d_inode->i_mutex); - -	list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child) -		if (dev->d_inode) -			update_dev(dev); - -	mutex_unlock(&bus->d_inode->i_mutex); -} - -static void update_sb(struct super_block *sb) -{ -	struct dentry *root = sb->s_root; -	struct dentry *bus = NULL; - -	if (!root) -		return; - -	mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); - -	list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { -		if (bus->d_inode) { -			switch (S_IFMT & bus->d_inode->i_mode) { -			case S_IFDIR: -				update_bus(bus); -				break; -			case S_IFREG: -				update_special(bus); -				break; -			default: -				printk(KERN_WARNING "usbfs: Unknown node %s " -				       "mode %x found on remount!\n", -				       bus->d_name.name, bus->d_inode->i_mode); -				break; -			} -		} -	} - -	mutex_unlock(&root->d_inode->i_mutex); -} - -static int remount(struct super_block *sb, int *flags, char *data) -{ -	/* If this is not a real mount, -	 * i.e. it's a simple_pin_fs from create_special_files, -	 * then ignore it. -	 */ -	if (ignore_mount) -		return 0; - -	if (parse_options(sb, data)) { -		printk(KERN_WARNING "usbfs: mount parameter error.\n"); -		return -EINVAL; -	} - -	if (usbfs_mount && usbfs_mount->mnt_sb) -		update_sb(usbfs_mount->mnt_sb); - -	return 0; -} - -static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev) -{ -	struct inode *inode = new_inode(sb); - -	if (inode) { -		inode->i_ino = get_next_ino(); -		inode->i_mode = mode; -		inode->i_uid = current_fsuid(); -		inode->i_gid = current_fsgid(); -		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; -		switch (mode & S_IFMT) { -		default: -			init_special_inode(inode, mode, dev); -			break; -		case S_IFREG: -			inode->i_fop = &default_file_operations; -			break; -		case S_IFDIR: -			inode->i_op = &simple_dir_inode_operations; -			inode->i_fop = &simple_dir_operations; - -			/* directory inodes start off with i_nlink == 2 (for "." entry) */ -			inc_nlink(inode); -			break; -		} -	} -	return inode;  -} - -/* SMP-safe */ -static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode, -			dev_t dev) -{ -	struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev); -	int error = -EPERM; - -	if (dentry->d_inode) -		return -EEXIST; - -	if (inode) { -		d_instantiate(dentry, inode); -		dget(dentry); -		error = 0; -	} -	return error; -} - -static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode) -{ -	int res; - -	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; -	res = usbfs_mknod (dir, dentry, mode, 0); -	if (!res) -		inc_nlink(dir); -	return res; -} - -static int usbfs_create (struct inode *dir, struct dentry *dentry, int mode) -{ -	mode = (mode & S_IALLUGO) | S_IFREG; -	return usbfs_mknod (dir, dentry, mode, 0); -} - -static inline int usbfs_positive (struct dentry *dentry) -{ -	return dentry->d_inode && !d_unhashed(dentry); -} - -static int usbfs_empty (struct dentry *dentry) -{ -	struct list_head *list; - -	spin_lock(&dcache_lock); - -	list_for_each(list, &dentry->d_subdirs) { -		struct dentry *de = list_entry(list, struct dentry, d_u.d_child); -		if (usbfs_positive(de)) { -			spin_unlock(&dcache_lock); -			return 0; -		} -	} - -	spin_unlock(&dcache_lock); -	return 1; -} - -static int usbfs_unlink (struct inode *dir, struct dentry *dentry) -{ -	struct inode *inode = dentry->d_inode; -	mutex_lock(&inode->i_mutex); -	drop_nlink(dentry->d_inode); -	dput(dentry); -	mutex_unlock(&inode->i_mutex); -	d_delete(dentry); -	return 0; -} - -static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) -{ -	int error = -ENOTEMPTY; -	struct inode * inode = dentry->d_inode; - -	mutex_lock(&inode->i_mutex); -	dentry_unhash(dentry); -	if (usbfs_empty(dentry)) { -		dont_mount(dentry); -		drop_nlink(dentry->d_inode); -		drop_nlink(dentry->d_inode); -		dput(dentry); -		inode->i_flags |= S_DEAD; -		drop_nlink(dir); -		error = 0; -	} -	mutex_unlock(&inode->i_mutex); -	if (!error) -		d_delete(dentry); -	dput(dentry); -	return error; -} - - -/* default file operations */ -static ssize_t default_read_file (struct file *file, char __user *buf, -				  size_t count, loff_t *ppos) -{ -	return 0; -} - -static ssize_t default_write_file (struct file *file, const char __user *buf, -				   size_t count, loff_t *ppos) -{ -	return count; -} - -static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) -{ -	loff_t retval = -EINVAL; - -	mutex_lock(&file->f_path.dentry->d_inode->i_mutex); -	switch(orig) { -	case 0: -		if (offset > 0) { -			file->f_pos = offset; -			retval = file->f_pos; -		}  -		break; -	case 1: -		if ((offset + file->f_pos) > 0) { -			file->f_pos += offset; -			retval = file->f_pos; -		}  -		break; -	default: -		break; -	} -	mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); -	return retval; -} - -static int default_open (struct inode *inode, struct file *file) -{ -	if (inode->i_private) -		file->private_data = inode->i_private; - -	return 0; -} - -static const struct file_operations default_file_operations = { -	.read =		default_read_file, -	.write =	default_write_file, -	.open =		default_open, -	.llseek =	default_file_lseek, -}; - -static const struct super_operations usbfs_ops = { -	.statfs =	simple_statfs, -	.drop_inode =	generic_delete_inode, -	.remount_fs =	remount, -	.show_options = usbfs_show_options, -}; - -static int usbfs_fill_super(struct super_block *sb, void *data, int silent) -{ -	struct inode *inode; -	struct dentry *root; - -	sb->s_blocksize = PAGE_CACHE_SIZE; -	sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -	sb->s_magic = USBDEVICE_SUPER_MAGIC; -	sb->s_op = &usbfs_ops; -	sb->s_time_gran = 1; -	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0); - -	if (!inode) { -		dbg("%s: could not get inode!",__func__); -		return -ENOMEM; -	} - -	root = d_alloc_root(inode); -	if (!root) { -		dbg("%s: could not get root dentry!",__func__); -		iput(inode); -		return -ENOMEM; -	} -	sb->s_root = root; -	return 0; -} - -/* - * fs_create_by_name - create a file, given a name - * @name:	name of file - * @mode:	type of file - * @parent:	dentry of directory to create it in - * @dentry:	resulting dentry of file - * - * This function handles both regular files and directories. - */ -static int fs_create_by_name (const char *name, mode_t mode, -			      struct dentry *parent, struct dentry **dentry) -{ -	int error = 0; - -	/* If the parent is not specified, we create it in the root. -	 * We need the root dentry to do this, which is in the super  -	 * block. A pointer to that is in the struct vfsmount that we -	 * have around. -	 */ -	if (!parent ) { -		if (usbfs_mount && usbfs_mount->mnt_sb) { -			parent = usbfs_mount->mnt_sb->s_root; -		} -	} - -	if (!parent) { -		dbg("Ah! can not find a parent!"); -		return -EFAULT; -	} - -	*dentry = NULL; -	mutex_lock(&parent->d_inode->i_mutex); -	*dentry = lookup_one_len(name, parent, strlen(name)); -	if (!IS_ERR(*dentry)) { -		if ((mode & S_IFMT) == S_IFDIR) -			error = usbfs_mkdir (parent->d_inode, *dentry, mode); -		else  -			error = usbfs_create (parent->d_inode, *dentry, mode); -	} else -		error = PTR_ERR(*dentry); -	mutex_unlock(&parent->d_inode->i_mutex); - -	return error; -} - -static struct dentry *fs_create_file (const char *name, mode_t mode, -				      struct dentry *parent, void *data, -				      const struct file_operations *fops, -				      uid_t uid, gid_t gid) -{ -	struct dentry *dentry; -	int error; - -	dbg("creating file '%s'",name); - -	error = fs_create_by_name (name, mode, parent, &dentry); -	if (error) { -		dentry = NULL; -	} else { -		if (dentry->d_inode) { -			if (data) -				dentry->d_inode->i_private = data; -			if (fops) -				dentry->d_inode->i_fop = fops; -			dentry->d_inode->i_uid = uid; -			dentry->d_inode->i_gid = gid; -		} -	} - -	return dentry; -} - -static void fs_remove_file (struct dentry *dentry) -{ -	struct dentry *parent = dentry->d_parent; -	 -	if (!parent || !parent->d_inode) -		return; - -	mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT); -	if (usbfs_positive(dentry)) { -		if (dentry->d_inode) { -			if (S_ISDIR(dentry->d_inode->i_mode)) -				usbfs_rmdir(parent->d_inode, dentry); -			else -				usbfs_unlink(parent->d_inode, dentry); -		dput(dentry); -		} -	} -	mutex_unlock(&parent->d_inode->i_mutex); -} - -/* --------------------------------------------------------------------- */ - -static struct dentry *usb_mount(struct file_system_type *fs_type, -	int flags, const char *dev_name, void *data) -{ -	return mount_single(fs_type, flags, data, usbfs_fill_super); -} - -static struct file_system_type usb_fs_type = { -	.owner =	THIS_MODULE, -	.name =		"usbfs", -	.mount =	usb_mount, -	.kill_sb =	kill_litter_super, -}; - -/* --------------------------------------------------------------------- */ - -static int create_special_files (void) -{ -	struct dentry *parent; -	int retval; - -	/* the simple_pin_fs calls will call remount with no options -	 * without this flag that would overwrite the real mount options (if any) -	 */ -	ignore_mount = 1; - -	/* create the devices special file */ -	retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); -	if (retval) { -		printk(KERN_ERR "Unable to get usbfs mount\n"); -		goto exit; -	} - -	ignore_mount = 0; - -	parent = usbfs_mount->mnt_sb->s_root; -	devices_usbfs_dentry = fs_create_file ("devices", -					       listmode | S_IFREG, parent, -					       NULL, &usbfs_devices_fops, -					       listuid, listgid); -	if (devices_usbfs_dentry == NULL) { -		printk(KERN_ERR "Unable to create devices usbfs file\n"); -		retval = -ENODEV; -		goto error_clean_mounts; -	} - -	goto exit; -	 -error_clean_mounts: -	simple_release_fs(&usbfs_mount, &usbfs_mount_count); -exit: -	return retval; -} - -static void remove_special_files (void) -{ -	if (devices_usbfs_dentry) -		fs_remove_file (devices_usbfs_dentry); -	devices_usbfs_dentry = NULL; -	simple_release_fs(&usbfs_mount, &usbfs_mount_count); -} - -void usbfs_update_special (void) -{ -	struct inode *inode; - -	if (devices_usbfs_dentry) { -		inode = devices_usbfs_dentry->d_inode; -		if (inode) -			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; -	} -} - -static void usbfs_add_bus(struct usb_bus *bus) -{ -	struct dentry *parent; -	char name[8]; -	int retval; - -	/* create the special files if this is the first bus added */ -	if (num_buses == 0) { -		retval = create_special_files(); -		if (retval) -			return; -	} -	++num_buses; - -	sprintf (name, "%03d", bus->busnum); - -	parent = usbfs_mount->mnt_sb->s_root; -	bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent, -					    bus, NULL, busuid, busgid); -	if (bus->usbfs_dentry == NULL) { -		printk(KERN_ERR "Error creating usbfs bus entry\n"); -		return; -	} -} - -static void usbfs_remove_bus(struct usb_bus *bus) -{ -	if (bus->usbfs_dentry) { -		fs_remove_file (bus->usbfs_dentry); -		bus->usbfs_dentry = NULL; -	} - -	--num_buses; -	if (num_buses <= 0) { -		remove_special_files(); -		num_buses = 0; -	} -} - -static void usbfs_add_device(struct usb_device *dev) -{ -	char name[8]; -	int i; -	int i_size; - -	sprintf (name, "%03d", dev->devnum); -	dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG, -					    dev->bus->usbfs_dentry, dev, -					    &usbdev_file_operations, -					    devuid, devgid); -	if (dev->usbfs_dentry == NULL) { -		printk(KERN_ERR "Error creating usbfs device entry\n"); -		return; -	} - -	/* Set the size of the device's file to be -	 * equal to the size of the device descriptors. */ -	i_size = sizeof (struct usb_device_descriptor); -	for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) { -		struct usb_config_descriptor *config = -			(struct usb_config_descriptor *)dev->rawdescriptors[i]; -		i_size += le16_to_cpu(config->wTotalLength); -	} -	if (dev->usbfs_dentry->d_inode) -		dev->usbfs_dentry->d_inode->i_size = i_size; -} - -static void usbfs_remove_device(struct usb_device *dev) -{ -	if (dev->usbfs_dentry) { -		fs_remove_file (dev->usbfs_dentry); -		dev->usbfs_dentry = NULL; -	} -} - -static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) -{ -	switch (action) { -	case USB_DEVICE_ADD: -		usbfs_add_device(dev); -		break; -	case USB_DEVICE_REMOVE: -		usbfs_remove_device(dev); -		break; -	case USB_BUS_ADD: -		usbfs_add_bus(dev); -		break; -	case USB_BUS_REMOVE: -		usbfs_remove_bus(dev); -	} - -	usbfs_update_special(); -	usbfs_conn_disc_event(); -	return NOTIFY_OK; -} - -static struct notifier_block usbfs_nb = { -	.notifier_call = 	usbfs_notify, -}; - -/* --------------------------------------------------------------------- */ - -static struct proc_dir_entry *usbdir = NULL; - -int __init usbfs_init(void) -{ -	int retval; - -	retval = register_filesystem(&usb_fs_type); -	if (retval) -		return retval; - -	usb_register_notify(&usbfs_nb); - -	/* create mount point for usbfs */ -	usbdir = proc_mkdir("bus/usb", NULL); - -	return 0; -} - -void usbfs_cleanup(void) -{ -	usb_unregister_notify(&usbfs_nb); -	unregister_filesystem(&usb_fs_type); -	if (usbdir) -		remove_proc_entry("bus/usb", NULL); -} - diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d6e3e410477..0c8a7fc4dad 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -6,7 +6,6 @@  #include <linux/usb.h>  #include <linux/module.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/mm.h>  #include <linux/timer.h>  #include <linux/ctype.h> @@ -119,15 +118,15 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,   * This function sends a simple control message to a specified endpoint and   * waits for the message to complete, or timeout.   * - * If successful, it returns the number of bytes transferred, otherwise a - * negative error number. - *   * Don't use this function from within an interrupt context, like a bottom half   * handler.  If you need an asynchronous message, or need to send a message   * from within interrupt context, use usb_submit_urb().   * If a thread in your driver uses this call, make sure your disconnect()   * method can wait for it to complete.  Since you don't have a handle on the   * URB used, you can't cancel the request. + * + * Return: If successful, the number of bytes transferred. Otherwise, a negative + * error number.   */  int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,  		    __u8 requesttype, __u16 value, __u16 index, void *data, @@ -146,8 +145,6 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,  	dr->wIndex = cpu_to_le16(index);  	dr->wLength = cpu_to_le16(size); -	/* dbg("usb_control_msg"); */ -  	ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);  	kfree(dr); @@ -172,15 +169,16 @@ EXPORT_SYMBOL_GPL(usb_control_msg);   * This function sends a simple interrupt message to a specified endpoint and   * waits for the message to complete, or timeout.   * - * If successful, it returns 0, otherwise a negative error number.  The number - * of actual bytes transferred will be stored in the actual_length paramater. - *   * Don't use this function from within an interrupt context, like a bottom half   * handler.  If you need an asynchronous message, or need to send a message   * from within interrupt context, use usb_submit_urb() If a thread in your   * driver uses this call, make sure your disconnect() method can wait for it to   * complete.  Since you don't have a handle on the URB used, you can't cancel   * the request. + * + * Return: + * If successful, 0. Otherwise a negative error number. The number of actual + * bytes transferred will be stored in the @actual_length parameter.   */  int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,  		      void *data, int len, int *actual_length, int timeout) @@ -205,9 +203,6 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg);   * This function sends a simple bulk message to a specified endpoint   * and waits for the message to complete, or timeout.   * - * If successful, it returns 0, otherwise a negative error number.  The number - * of actual bytes transferred will be stored in the actual_length paramater. - *   * Don't use this function from within an interrupt context, like a bottom half   * handler.  If you need an asynchronous message, or need to send a message   * from within interrupt context, use usb_submit_urb() If a thread in your @@ -219,6 +214,11 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg);   * users are forced to abuse this routine by using it to submit URBs for   * interrupt endpoints.  We will take the liberty of creating an interrupt URB   * (with the default interval) if the target is an interrupt endpoint. + * + * Return: + * If successful, 0. Otherwise a negative error number. The number of actual + * bytes transferred will be stored in the @actual_length parameter. + *   */  int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,  		 void *data, int len, int *actual_length, int timeout) @@ -254,7 +254,7 @@ static void sg_clean(struct usb_sg_request *io)  {  	if (io->urbs) {  		while (io->entries--) -			usb_free_urb(io->urbs [io->entries]); +			usb_free_urb(io->urbs[io->entries]);  		kfree(io->urbs);  		io->urbs = NULL;  	} @@ -302,22 +302,22 @@ static void sg_complete(struct urb *urb)  		 */  		spin_unlock(&io->lock);  		for (i = 0, found = 0; i < io->entries; i++) { -			if (!io->urbs [i] || !io->urbs [i]->dev) +			if (!io->urbs[i] || !io->urbs[i]->dev)  				continue;  			if (found) { -				retval = usb_unlink_urb(io->urbs [i]); +				retval = usb_unlink_urb(io->urbs[i]);  				if (retval != -EINPROGRESS &&  				    retval != -ENODEV && -				    retval != -EBUSY) +				    retval != -EBUSY && +				    retval != -EIDRM)  					dev_err(&io->dev->dev,  						"%s, unlink --> %d\n",  						__func__, retval); -			} else if (urb == io->urbs [i]) +			} else if (urb == io->urbs[i])  				found = 1;  		}  		spin_lock(&io->lock);  	} -	urb->dev = NULL;  	/* on the last completion, signal usb_sg_wait() */  	io->bytes += urb->actual_length; @@ -343,9 +343,9 @@ static void sg_complete(struct urb *urb)   * 	send every byte identified in the list.   * @mem_flags: SLAB_* flags affecting memory allocations in this call   * - * Returns zero for success, else a negative errno value.  This initializes a - * scatter/gather request, allocating resources such as I/O mappings and urb - * memory (except maybe memory used by USB controller drivers). + * This initializes a scatter/gather request, allocating resources such as + * I/O mappings and urb memory (except maybe memory used by USB controller + * drivers).   *   * The request must be issued using usb_sg_wait(), which waits for the I/O to   * complete (or to be canceled) and then cleans up all resources allocated by @@ -353,6 +353,8 @@ static void sg_complete(struct urb *urb)   *   * The request may be canceled with usb_sg_cancel(), either before or after   * usb_sg_wait() is called. + * + * Return: Zero for success, else a negative errno value.   */  int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,  		unsigned pipe, unsigned	period, struct scatterlist *sg, @@ -381,7 +383,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,  	}  	/* initialize all the urbs we'll use */ -	io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); +	io->urbs = kmalloc(io->entries * sizeof(*io->urbs), mem_flags);  	if (!io->urbs)  		goto nomem; @@ -435,7 +437,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,  			len = sg->length;  			if (length) { -				len = min_t(unsigned, len, length); +				len = min_t(size_t, len, length);  				length -= len;  				if (length == 0)  					io->entries = i + 1; @@ -513,9 +515,9 @@ void usb_sg_wait(struct usb_sg_request *io)  		int retval;  		io->urbs[i]->dev = io->dev; -		retval = usb_submit_urb(io->urbs [i], GFP_ATOMIC); +		retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC); -		/* after we submit, let completions or cancelations fire; +		/* after we submit, let completions or cancellations fire;  		 * we handshake using io->status.  		 */  		spin_unlock_irq(&io->lock); @@ -524,7 +526,6 @@ void usb_sg_wait(struct usb_sg_request *io)  		case -ENXIO:	/* hc didn't queue this one */  		case -EAGAIN:  		case -ENOMEM: -			io->urbs[i]->dev = NULL;  			retval = 0;  			yield();  			break; @@ -542,7 +543,6 @@ void usb_sg_wait(struct usb_sg_request *io)  			/* fail any uncompleted urbs */  		default: -			io->urbs[i]->dev = NULL;  			io->urbs[i]->status = retval;  			dev_dbg(&io->dev->dev, "%s, submit --> %d\n",  				__func__, retval); @@ -590,10 +590,13 @@ void usb_sg_cancel(struct usb_sg_request *io)  		for (i = 0; i < io->entries; i++) {  			int retval; -			if (!io->urbs [i]->dev) +			if (!io->urbs[i]->dev)  				continue; -			retval = usb_unlink_urb(io->urbs [i]); -			if (retval != -EINPROGRESS && retval != -EBUSY) +			retval = usb_unlink_urb(io->urbs[i]); +			if (retval != -EINPROGRESS +					&& retval != -ENODEV +					&& retval != -EBUSY +					&& retval != -EIDRM)  				dev_warn(&io->dev->dev, "%s, unlink --> %d\n",  					__func__, retval);  		} @@ -624,7 +627,7 @@ EXPORT_SYMBOL_GPL(usb_sg_cancel);   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns the number of bytes received on success, or else the status code + * Return: The number of bytes received on success, or else the status code   * returned by the underlying usb_control_msg() call.   */  int usb_get_descriptor(struct usb_device *dev, unsigned char type, @@ -672,7 +675,7 @@ EXPORT_SYMBOL_GPL(usb_get_descriptor);   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns the number of bytes received on success, or else the status code + * Return: The number of bytes received on success, or else the status code   * returned by the underlying usb_control_msg() call.   */  static int usb_get_string(struct usb_device *dev, unsigned short langid, @@ -806,7 +809,7 @@ static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns length of the string (>= 0) or usb_control_msg status (< 0). + * Return: length of the string (>= 0) or usb_control_msg status (< 0).   */  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)  { @@ -854,8 +857,8 @@ EXPORT_SYMBOL_GPL(usb_string);   * @udev: the device whose string descriptor is being read   * @index: the descriptor index   * - * Returns a pointer to a kmalloc'ed buffer containing the descriptor string, - * or NULL if the index is 0 or the string could not be read. + * Return: A pointer to a kmalloc'ed buffer containing the descriptor string, + * or %NULL if the index is 0 or the string could not be read.   */  char *usb_cache_string(struct usb_device *udev, int index)  { @@ -895,7 +898,7 @@ char *usb_cache_string(struct usb_device *udev, int index)   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns the number of bytes received on success, or else the status code + * Return: The number of bytes received on success, or else the status code   * returned by the underlying usb_control_msg() call.   */  int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) @@ -935,13 +938,13 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns the number of bytes received on success, or else the status code - * returned by the underlying usb_control_msg() call. + * Returns 0 and the status value in *@data (in host byte order) on success, + * or else the status code from the underlying usb_control_msg() call.   */  int usb_get_status(struct usb_device *dev, int type, int target, void *data)  {  	int ret; -	u16 *status = kmalloc(sizeof(*status), GFP_KERNEL); +	__le16 *status = kmalloc(sizeof(*status), GFP_KERNEL);  	if (!status)  		return -ENOMEM; @@ -950,7 +953,12 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data)  		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, status,  		sizeof(*status), USB_CTRL_GET_TIMEOUT); -	*(u16 *)data = *status; +	if (ret == 2) { +		*(u16 *) data = le16_to_cpu(*status); +		ret = 0; +	} else if (ret >= 0) { +		ret = -EIO; +	}  	kfree(status);  	return ret;  } @@ -976,7 +984,7 @@ EXPORT_SYMBOL_GPL(usb_get_status);   *   * This call is synchronous, and may not be used in an interrupt context.   * - * Returns zero on success, or else the status code returned by the + * Return: Zero on success, or else the status code returned by the   * underlying usb_control_msg() call.   */  int usb_clear_halt(struct usb_device *dev, int pipe) @@ -1139,11 +1147,20 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,  void usb_disable_device(struct usb_device *dev, int skip_ep0)  {  	int i; +	struct usb_hcd *hcd = bus_to_hcd(dev->bus);  	/* getting rid of interfaces will disconnect  	 * any drivers bound to them (a key side effect)  	 */  	if (dev->actconfig) { +		/* +		 * FIXME: In order to avoid self-deadlock involving the +		 * bandwidth_mutex, we have to mark all the interfaces +		 * before unregistering any of them. +		 */ +		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) +			dev->actconfig->interface[i]->unregistering = 1; +  		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {  			struct usb_interface	*interface; @@ -1153,7 +1170,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  				continue;  			dev_dbg(&dev->dev, "unregistering interface %s\n",  				dev_name(&interface->dev)); -			interface->unregistering = 1;  			remove_intf_ep_devs(interface);  			device_del(&interface->dev);  		} @@ -1165,6 +1181,12 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  			put_device(&dev->actconfig->interface[i]->dev);  			dev->actconfig->interface[i] = NULL;  		} + +		if (dev->usb2_hw_lpm_enabled == 1) +			usb_set_usb2_hardware_lpm(dev, 0); +		usb_unlocked_disable_lpm(dev); +		usb_disable_ltm(dev); +  		dev->actconfig = NULL;  		if (dev->state == USB_STATE_CONFIGURED)  			usb_set_device_state(dev, USB_STATE_ADDRESS); @@ -1172,6 +1194,18 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  	dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,  		skip_ep0 ? "non-ep0" : "all"); +	if (hcd->driver->check_bandwidth) { +		/* First pass: Cancel URBs, leave endpoint pointers intact. */ +		for (i = skip_ep0; i < 16; ++i) { +			usb_disable_endpoint(dev, i, false); +			usb_disable_endpoint(dev, i + USB_DIR_IN, false); +		} +		/* Remove endpoints from the host controller internal state */ +		mutex_lock(hcd->bandwidth_mutex); +		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +		mutex_unlock(hcd->bandwidth_mutex); +		/* Second pass: remove endpoint pointers */ +	}  	for (i = skip_ep0; i < 16; ++i) {  		usb_disable_endpoint(dev, i, true);  		usb_disable_endpoint(dev, i + USB_DIR_IN, true); @@ -1251,7 +1285,7 @@ void usb_enable_interface(struct usb_device *dev,   * endpoints in that interface; all such urbs must first be completed   * (perhaps forced by unlinking).   * - * Returns zero on success, or else the status code returned by the + * Return: Zero on success, or else the status code returned by the   * underlying usb_control_msg() call.   */  int usb_set_interface(struct usb_device *dev, int interface, int alternate) @@ -1259,8 +1293,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  	struct usb_interface *iface;  	struct usb_host_interface *alt;  	struct usb_hcd *hcd = bus_to_hcd(dev->bus); -	int ret; -	int manual = 0; +	int i, ret, manual = 0;  	unsigned int epaddr;  	unsigned int pipe; @@ -1273,6 +1306,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  			interface);  		return -EINVAL;  	} +	if (iface->unregistering) +		return -ENODEV;  	alt = usb_altnum_to_altsetting(iface, alternate);  	if (!alt) { @@ -1284,12 +1319,25 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  	/* Make sure we have enough bandwidth for this alternate interface.  	 * Remove the current alt setting and add the new alt setting.  	 */ -	mutex_lock(&hcd->bandwidth_mutex); +	mutex_lock(hcd->bandwidth_mutex); +	/* Disable LPM, and re-enable it once the new alt setting is installed, +	 * so that the xHCI driver can recalculate the U1/U2 timeouts. +	 */ +	if (usb_disable_lpm(dev)) { +		dev_err(&iface->dev, "%s Failed to disable LPM\n.", __func__); +		mutex_unlock(hcd->bandwidth_mutex); +		return -ENOMEM; +	} +	/* Changing alt-setting also frees any allocated streams */ +	for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++) +		iface->cur_altsetting->endpoint[i].streams = 0; +  	ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);  	if (ret < 0) {  		dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",  				alternate); -		mutex_unlock(&hcd->bandwidth_mutex); +		usb_enable_lpm(dev); +		mutex_unlock(hcd->bandwidth_mutex);  		return ret;  	} @@ -1311,10 +1359,11 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  	} else if (ret < 0) {  		/* Re-instate the old alt setting */  		usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); -		mutex_unlock(&hcd->bandwidth_mutex); +		usb_enable_lpm(dev); +		mutex_unlock(hcd->bandwidth_mutex);  		return ret;  	} -	mutex_unlock(&hcd->bandwidth_mutex); +	mutex_unlock(hcd->bandwidth_mutex);  	/* FIXME drivers shouldn't need to replicate/bugfix the logic here  	 * when they implement async or easily-killable versions of this or @@ -1331,6 +1380,9 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  	iface->cur_altsetting = alt; +	/* Now that the interface is installed, re-enable LPM. */ +	usb_unlocked_enable_lpm(dev); +  	/* If the interface only has one altsetting and the device didn't  	 * accept the request, we attempt to carry out the equivalent action  	 * by manually clearing the HALT feature for each endpoint in the @@ -1390,7 +1442,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);   *   * The caller must own the device lock.   * - * Returns zero on success, else a negative error code. + * Return: Zero on success, else a negative error code.   */  int usb_reset_configuration(struct usb_device *dev)  { @@ -1413,7 +1465,15 @@ int usb_reset_configuration(struct usb_device *dev)  	config = dev->actconfig;  	retval = 0; -	mutex_lock(&hcd->bandwidth_mutex); +	mutex_lock(hcd->bandwidth_mutex); +	/* Disable LPM, and re-enable it once the configuration is reset, so +	 * that the xHCI driver can recalculate the U1/U2 timeouts. +	 */ +	if (usb_disable_lpm(dev)) { +		dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); +		mutex_unlock(hcd->bandwidth_mutex); +		return -ENOMEM; +	}  	/* Make sure we have enough bandwidth for each alternate setting 0 */  	for (i = 0; i < config->desc.bNumInterfaces; i++) {  		struct usb_interface *intf = config->interface[i]; @@ -1442,7 +1502,8 @@ reset_old_alts:  				usb_hcd_alloc_bandwidth(dev, NULL,  						alt, intf->cur_altsetting);  		} -		mutex_unlock(&hcd->bandwidth_mutex); +		usb_enable_lpm(dev); +		mutex_unlock(hcd->bandwidth_mutex);  		return retval;  	}  	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -1451,7 +1512,7 @@ reset_old_alts:  			NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (retval < 0)  		goto reset_old_alts; -	mutex_unlock(&hcd->bandwidth_mutex); +	mutex_unlock(hcd->bandwidth_mutex);  	/* re-init hc/hcd interface/endpoint state */  	for (i = 0; i < config->desc.bNumInterfaces; i++) { @@ -1479,6 +1540,8 @@ reset_old_alts:  			create_intf_ep_devs(intf);  		}  	} +	/* Now that the interfaces are installed, re-enable LPM. */ +	usb_unlocked_enable_lpm(dev);  	return 0;  }  EXPORT_SYMBOL_GPL(usb_reset_configuration); @@ -1493,7 +1556,6 @@ static void usb_release_interface(struct device *dev)  	kfree(intf);  } -#ifdef	CONFIG_HOTPLUG  static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)  {  	struct usb_device *usb_dev; @@ -1512,7 +1574,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)  	if (add_uevent_var(env,  		   "MODALIAS=usb:" -		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", +		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",  		   le16_to_cpu(usb_dev->descriptor.idVendor),  		   le16_to_cpu(usb_dev->descriptor.idProduct),  		   le16_to_cpu(usb_dev->descriptor.bcdDevice), @@ -1521,20 +1583,13 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)  		   usb_dev->descriptor.bDeviceProtocol,  		   alt->desc.bInterfaceClass,  		   alt->desc.bInterfaceSubClass, -		   alt->desc.bInterfaceProtocol)) +		   alt->desc.bInterfaceProtocol, +		   alt->desc.bInterfaceNumber))  		return -ENOMEM;  	return 0;  } -#else - -static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) -{ -	return -ENODEV; -} -#endif	/* CONFIG_HOTPLUG */ -  struct device_type usb_if_device_type = {  	.name =		"usb_interface",  	.release =	usb_release_interface, @@ -1712,7 +1767,7 @@ free_interfaces:  			}  		} -		i = dev->bus_mA - cp->desc.bMaxPower * 2; +		i = dev->bus_mA - usb_get_max_power(dev, cp);  		if (i < 0)  			dev_warn(&dev->dev, "new config #%d exceeds power "  					"limit by %dmA\n", @@ -1739,36 +1794,28 @@ free_interfaces:  	 * host controller will not allow submissions to dropped endpoints.  If  	 * this call fails, the device state is unchanged.  	 */ -	mutex_lock(&hcd->bandwidth_mutex); -	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); -	if (ret < 0) { -		mutex_unlock(&hcd->bandwidth_mutex); -		usb_autosuspend_device(dev); +	mutex_lock(hcd->bandwidth_mutex); +	/* Disable LPM, and re-enable it once the new configuration is +	 * installed, so that the xHCI driver can recalculate the U1/U2 +	 * timeouts. +	 */ +	if (dev->actconfig && usb_disable_lpm(dev)) { +		dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); +		mutex_unlock(hcd->bandwidth_mutex); +		ret = -ENOMEM;  		goto free_interfaces;  	} - -	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), -			      USB_REQ_SET_CONFIGURATION, 0, configuration, 0, -			      NULL, 0, USB_CTRL_SET_TIMEOUT); +	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  	if (ret < 0) { -		/* All the old state is gone, so what else can we do? -		 * The device is probably useless now anyway. -		 */ -		cp = NULL; -	} - -	dev->actconfig = cp; -	if (!cp) { -		usb_set_device_state(dev, USB_STATE_ADDRESS); -		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); -		mutex_unlock(&hcd->bandwidth_mutex); +		if (dev->actconfig) +			usb_enable_lpm(dev); +		mutex_unlock(hcd->bandwidth_mutex);  		usb_autosuspend_device(dev);  		goto free_interfaces;  	} -	mutex_unlock(&hcd->bandwidth_mutex); -	usb_set_device_state(dev, USB_STATE_CONFIGURED); -	/* Initialize the new interface structures and the +	/* +	 * Initialize the new interface structures and the  	 * hc/hcd/usbcore interface/endpoint state.  	 */  	for (i = 0; i < nintf; ++i) { @@ -1780,7 +1827,6 @@ free_interfaces:  		intfc = cp->intf_cache[i];  		intf->altsetting = intfc->altsetting;  		intf->num_altsetting = intfc->num_altsetting; -		intf->intf_assoc = find_iad(dev, cp, i);  		kref_get(&intfc->ref);  		alt = usb_altnum_to_altsetting(intf, 0); @@ -1793,6 +1839,8 @@ free_interfaces:  		if (!alt)  			alt = &intf->altsetting[0]; +		intf->intf_assoc = +			find_iad(dev, cp, alt->desc.bInterfaceNumber);  		intf->cur_altsetting = alt;  		usb_enable_interface(dev, intf, true);  		intf->dev.parent = &dev->dev; @@ -1804,16 +1852,51 @@ free_interfaces:  		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);  		intf->minor = -1;  		device_initialize(&intf->dev); +		pm_runtime_no_callbacks(&intf->dev);  		dev_set_name(&intf->dev, "%d-%s:%d.%d",  			dev->bus->busnum, dev->devpath,  			configuration, alt->desc.bInterfaceNumber);  	}  	kfree(new_interfaces); +	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), +			      USB_REQ_SET_CONFIGURATION, 0, configuration, 0, +			      NULL, 0, USB_CTRL_SET_TIMEOUT); +	if (ret < 0 && cp) { +		/* +		 * All the old state is gone, so what else can we do? +		 * The device is probably useless now anyway. +		 */ +		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +		for (i = 0; i < nintf; ++i) { +			usb_disable_interface(dev, cp->interface[i], true); +			put_device(&cp->interface[i]->dev); +			cp->interface[i] = NULL; +		} +		cp = NULL; +	} + +	dev->actconfig = cp; +	mutex_unlock(hcd->bandwidth_mutex); + +	if (!cp) { +		usb_set_device_state(dev, USB_STATE_ADDRESS); + +		/* Leave LPM disabled while the device is unconfigured. */ +		usb_autosuspend_device(dev); +		return ret; +	} +	usb_set_device_state(dev, USB_STATE_CONFIGURED); +  	if (cp->string == NULL &&  			!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))  		cp->string = usb_cache_string(dev, cp->desc.iConfiguration); +	/* Now that the interfaces are installed, re-enable LPM. */ +	usb_unlocked_enable_lpm(dev); +	/* Enable LTM if it was turned off by usb_disable_device. */ +	usb_enable_ltm(dev); +  	/* Now that all the interfaces are set up, register them  	 * to trigger binding of drivers to interfaces.  probe()  	 * routines may install different altsettings and may @@ -1840,6 +1923,7 @@ free_interfaces:  	usb_autosuspend_device(dev);  	return 0;  } +EXPORT_SYMBOL_GPL(usb_set_configuration);  static LIST_HEAD(set_config_list);  static DEFINE_SPINLOCK(set_config_lock); @@ -1901,7 +1985,7 @@ static void cancel_async_set_config(struct usb_device *udev)   * routine gets around the normal restrictions by using a work thread to   * submit the change-config request.   * - * Returns 0 if the request was successfully queued, error code otherwise. + * Return: 0 if the request was successfully queued, error code otherwise.   * The caller has no way to know whether the queued request will eventually   * succeed.   */ diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index 7542dce3f5a..7728c91dfa2 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c @@ -10,6 +10,7 @@  #include <linux/kernel.h> +#include <linux/export.h>  #include <linux/notifier.h>  #include <linux/usb.h>  #include <linux/mutex.h> diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c new file mode 100644 index 00000000000..fe1b6d0967e --- /dev/null +++ b/drivers/usb/core/port.c @@ -0,0 +1,484 @@ +/* + * usb port device code + * + * Copyright (C) 2012 Intel Corp + * + * Author: Lan Tianyu <tianyu.lan@intel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License + * for more details. + * + */ + +#include <linux/slab.h> +#include <linux/pm_qos.h> + +#include "hub.h" + +static int usb_port_block_power_off; + +static const struct attribute_group *port_dev_group[]; + +static ssize_t connect_type_show(struct device *dev, +				 struct device_attribute *attr, char *buf) +{ +	struct usb_port *port_dev = to_usb_port(dev); +	char *result; + +	switch (port_dev->connect_type) { +	case USB_PORT_CONNECT_TYPE_HOT_PLUG: +		result = "hotplug"; +		break; +	case USB_PORT_CONNECT_TYPE_HARD_WIRED: +		result = "hardwired"; +		break; +	case USB_PORT_NOT_USED: +		result = "not used"; +		break; +	default: +		result = "unknown"; +		break; +	} + +	return sprintf(buf, "%s\n", result); +} +static DEVICE_ATTR_RO(connect_type); + +static struct attribute *port_dev_attrs[] = { +	&dev_attr_connect_type.attr, +	NULL, +}; + +static struct attribute_group port_dev_attr_grp = { +	.attrs = port_dev_attrs, +}; + +static const struct attribute_group *port_dev_group[] = { +	&port_dev_attr_grp, +	NULL, +}; + +static void usb_port_device_release(struct device *dev) +{ +	struct usb_port *port_dev = to_usb_port(dev); + +	kfree(port_dev->req); +	kfree(port_dev); +} + +#ifdef CONFIG_PM_RUNTIME +static int usb_port_runtime_resume(struct device *dev) +{ +	struct usb_port *port_dev = to_usb_port(dev); +	struct usb_device *hdev = to_usb_device(dev->parent->parent); +	struct usb_interface *intf = to_usb_interface(dev->parent); +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); +	struct usb_device *udev = port_dev->child; +	struct usb_port *peer = port_dev->peer; +	int port1 = port_dev->portnum; +	int retval; + +	if (!hub) +		return -EINVAL; +	if (hub->in_reset) { +		set_bit(port1, hub->power_bits); +		return 0; +	} + +	/* +	 * Power on our usb3 peer before this usb2 port to prevent a usb3 +	 * device from degrading to its usb2 connection +	 */ +	if (!port_dev->is_superspeed && peer) +		pm_runtime_get_sync(&peer->dev); + +	usb_autopm_get_interface(intf); +	retval = usb_hub_set_port_power(hdev, hub, port1, true); +	msleep(hub_power_on_good_delay(hub)); +	if (udev && !retval) { +		/* +		 * Attempt to wait for usb hub port to be reconnected in order +		 * to make the resume procedure successful.  The device may have +		 * disconnected while the port was powered off, so ignore the +		 * return status. +		 */ +		retval = hub_port_debounce_be_connected(hub, port1); +		if (retval < 0) +			dev_dbg(&port_dev->dev, "can't get reconnection after setting port  power on, status %d\n", +					retval); +		retval = 0; + +		/* Force the child awake to revalidate after the power loss. */ +		if (!test_and_set_bit(port1, hub->child_usage_bits)) { +			pm_runtime_get_noresume(&port_dev->dev); +			pm_request_resume(&udev->dev); +		} +	} + +	usb_autopm_put_interface(intf); + +	return retval; +} + +static int usb_port_runtime_suspend(struct device *dev) +{ +	struct usb_port *port_dev = to_usb_port(dev); +	struct usb_device *hdev = to_usb_device(dev->parent->parent); +	struct usb_interface *intf = to_usb_interface(dev->parent); +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); +	struct usb_port *peer = port_dev->peer; +	int port1 = port_dev->portnum; +	int retval; + +	if (!hub) +		return -EINVAL; +	if (hub->in_reset) +		return -EBUSY; + +	if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) +			== PM_QOS_FLAGS_ALL) +		return -EAGAIN; + +	if (usb_port_block_power_off) +		return -EBUSY; + +	usb_autopm_get_interface(intf); +	retval = usb_hub_set_port_power(hdev, hub, port1, false); +	usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); +	if (!port_dev->is_superspeed) +		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); +	usb_autopm_put_interface(intf); + +	/* +	 * Our peer usb3 port may now be able to suspend, so +	 * asynchronously queue a suspend request to observe that this +	 * usb2 port is now off. +	 */ +	if (!port_dev->is_superspeed && peer) +		pm_runtime_put(&peer->dev); + +	return retval; +} +#endif + +static const struct dev_pm_ops usb_port_pm_ops = { +#ifdef CONFIG_PM_RUNTIME +	.runtime_suspend =	usb_port_runtime_suspend, +	.runtime_resume =	usb_port_runtime_resume, +#endif +}; + +struct device_type usb_port_device_type = { +	.name =		"usb_port", +	.release =	usb_port_device_release, +	.pm =		&usb_port_pm_ops, +}; + +static struct device_driver usb_port_driver = { +	.name = "usb", +	.owner = THIS_MODULE, +}; + +static int link_peers(struct usb_port *left, struct usb_port *right) +{ +	struct usb_port *ss_port, *hs_port; +	int rc; + +	if (left->peer == right && right->peer == left) +		return 0; + +	if (left->peer || right->peer) { +		struct usb_port *lpeer = left->peer; +		struct usb_port *rpeer = right->peer; +		char *method; + +		if (left->location && left->location == right->location) +			method = "location"; +		else +			method = "default"; + +		pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n", +			dev_name(&left->dev), dev_name(&right->dev), method, +			dev_name(&left->dev), +			lpeer ? dev_name(&lpeer->dev) : "none", +			dev_name(&right->dev), +			rpeer ? dev_name(&rpeer->dev) : "none"); +		return -EBUSY; +	} + +	rc = sysfs_create_link(&left->dev.kobj, &right->dev.kobj, "peer"); +	if (rc) +		return rc; +	rc = sysfs_create_link(&right->dev.kobj, &left->dev.kobj, "peer"); +	if (rc) { +		sysfs_remove_link(&left->dev.kobj, "peer"); +		return rc; +	} + +	/* +	 * We need to wake the HiSpeed port to make sure we don't race +	 * setting ->peer with usb_port_runtime_suspend().  Otherwise we +	 * may miss a suspend event for the SuperSpeed port. +	 */ +	if (left->is_superspeed) { +		ss_port = left; +		WARN_ON(right->is_superspeed); +		hs_port = right; +	} else { +		ss_port = right; +		WARN_ON(!right->is_superspeed); +		hs_port = left; +	} +	pm_runtime_get_sync(&hs_port->dev); + +	left->peer = right; +	right->peer = left; + +	/* +	 * The SuperSpeed reference is dropped when the HiSpeed port in +	 * this relationship suspends, i.e. when it is safe to allow a +	 * SuperSpeed connection to drop since there is no risk of a +	 * device degrading to its powered-off HiSpeed connection. +	 * +	 * Also, drop the HiSpeed ref taken above. +	 */ +	pm_runtime_get_sync(&ss_port->dev); +	pm_runtime_put(&hs_port->dev); + +	return 0; +} + +static void link_peers_report(struct usb_port *left, struct usb_port *right) +{ +	int rc; + +	rc = link_peers(left, right); +	if (rc == 0) { +		dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev)); +	} else { +		dev_warn(&left->dev, "failed to peer to %s (%d)\n", +				dev_name(&right->dev), rc); +		pr_warn_once("usb: port power management may be unreliable\n"); +		usb_port_block_power_off = 1; +	} +} + +static void unlink_peers(struct usb_port *left, struct usb_port *right) +{ +	struct usb_port *ss_port, *hs_port; + +	WARN(right->peer != left || left->peer != right, +			"%s and %s are not peers?\n", +			dev_name(&left->dev), dev_name(&right->dev)); + +	/* +	 * We wake the HiSpeed port to make sure we don't race its +	 * usb_port_runtime_resume() event which takes a SuperSpeed ref +	 * when ->peer is !NULL. +	 */ +	if (left->is_superspeed) { +		ss_port = left; +		hs_port = right; +	} else { +		ss_port = right; +		hs_port = left; +	} + +	pm_runtime_get_sync(&hs_port->dev); + +	sysfs_remove_link(&left->dev.kobj, "peer"); +	right->peer = NULL; +	sysfs_remove_link(&right->dev.kobj, "peer"); +	left->peer = NULL; + +	/* Drop the SuperSpeed ref held on behalf of the active HiSpeed port */ +	pm_runtime_put(&ss_port->dev); + +	/* Drop the ref taken above */ +	pm_runtime_put(&hs_port->dev); +} + +/* + * For each usb hub device in the system check to see if it is in the + * peer domain of the given port_dev, and if it is check to see if it + * has a port that matches the given port by location + */ +static int match_location(struct usb_device *peer_hdev, void *p) +{ +	int port1; +	struct usb_hcd *hcd, *peer_hcd; +	struct usb_port *port_dev = p, *peer; +	struct usb_hub *peer_hub = usb_hub_to_struct_hub(peer_hdev); +	struct usb_device *hdev = to_usb_device(port_dev->dev.parent->parent); + +	if (!peer_hub) +		return 0; + +	hcd = bus_to_hcd(hdev->bus); +	peer_hcd = bus_to_hcd(peer_hdev->bus); +	/* peer_hcd is provisional until we verify it against the known peer */ +	if (peer_hcd != hcd->shared_hcd) +		return 0; + +	for (port1 = 1; port1 <= peer_hdev->maxchild; port1++) { +		peer = peer_hub->ports[port1 - 1]; +		if (peer && peer->location == port_dev->location) { +			link_peers_report(port_dev, peer); +			return 1; /* done */ +		} +	} + +	return 0; +} + +/* + * Find the peer port either via explicit platform firmware "location" + * data, the peer hcd for root hubs, or the upstream peer relationship + * for all other hubs. + */ +static void find_and_link_peer(struct usb_hub *hub, int port1) +{ +	struct usb_port *port_dev = hub->ports[port1 - 1], *peer; +	struct usb_device *hdev = hub->hdev; +	struct usb_device *peer_hdev; +	struct usb_hub *peer_hub; + +	/* +	 * If location data is available then we can only peer this port +	 * by a location match, not the default peer (lest we create a +	 * situation where we need to go back and undo a default peering +	 * when the port is later peered by location data) +	 */ +	if (port_dev->location) { +		/* we link the peer in match_location() if found */ +		usb_for_each_dev(port_dev, match_location); +		return; +	} else if (!hdev->parent) { +		struct usb_hcd *hcd = bus_to_hcd(hdev->bus); +		struct usb_hcd *peer_hcd = hcd->shared_hcd; + +		if (!peer_hcd) +			return; + +		peer_hdev = peer_hcd->self.root_hub; +	} else { +		struct usb_port *upstream; +		struct usb_device *parent = hdev->parent; +		struct usb_hub *parent_hub = usb_hub_to_struct_hub(parent); + +		if (!parent_hub) +			return; + +		upstream = parent_hub->ports[hdev->portnum - 1]; +		if (!upstream || !upstream->peer) +			return; + +		peer_hdev = upstream->peer->child; +	} + +	peer_hub = usb_hub_to_struct_hub(peer_hdev); +	if (!peer_hub || port1 > peer_hdev->maxchild) +		return; + +	/* +	 * we found a valid default peer, last check is to make sure it +	 * does not have location data +	 */ +	peer = peer_hub->ports[port1 - 1]; +	if (peer && peer->location == 0) +		link_peers_report(port_dev, peer); +} + +int usb_hub_create_port_device(struct usb_hub *hub, int port1) +{ +	struct usb_port *port_dev; +	int retval; + +	port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); +	if (!port_dev) +		return -ENOMEM; + +	port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL); +	if (!port_dev->req) { +		kfree(port_dev); +		return -ENOMEM; +	} + +	hub->ports[port1 - 1] = port_dev; +	port_dev->portnum = port1; +	set_bit(port1, hub->power_bits); +	port_dev->dev.parent = hub->intfdev; +	port_dev->dev.groups = port_dev_group; +	port_dev->dev.type = &usb_port_device_type; +	port_dev->dev.driver = &usb_port_driver; +	if (hub_is_superspeed(hub->hdev)) +		port_dev->is_superspeed = 1; +	dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev), +			port1); +	mutex_init(&port_dev->status_lock); +	retval = device_register(&port_dev->dev); +	if (retval) { +		put_device(&port_dev->dev); +		return retval; +	} + +	/* Set default policy of port-poweroff disabled. */ +	retval = dev_pm_qos_add_request(&port_dev->dev, port_dev->req, +			DEV_PM_QOS_FLAGS, PM_QOS_FLAG_NO_POWER_OFF); +	if (retval < 0) { +		device_unregister(&port_dev->dev); +		return retval; +	} + +	find_and_link_peer(hub, port1); + +	/* +	 * Enable runtime pm and hold a refernce that hub_configure() +	 * will drop once the PM_QOS_NO_POWER_OFF flag state has been set +	 * and the hub has been fully registered (hdev->maxchild set). +	 */ +	pm_runtime_set_active(&port_dev->dev); +	pm_runtime_get_noresume(&port_dev->dev); +	pm_runtime_enable(&port_dev->dev); +	device_enable_async_suspend(&port_dev->dev); + +	/* +	 * Keep hidden the ability to enable port-poweroff if the hub +	 * does not support power switching. +	 */ +	if (!hub_is_port_power_switchable(hub)) +		return 0; + +	/* Attempt to let userspace take over the policy. */ +	retval = dev_pm_qos_expose_flags(&port_dev->dev, +			PM_QOS_FLAG_NO_POWER_OFF); +	if (retval < 0) { +		dev_warn(&port_dev->dev, "failed to expose pm_qos_no_poweroff\n"); +		return 0; +	} + +	/* Userspace owns the policy, drop the kernel 'no_poweroff' request. */ +	retval = dev_pm_qos_remove_request(port_dev->req); +	if (retval >= 0) { +		kfree(port_dev->req); +		port_dev->req = NULL; +	} +	return 0; +} + +void usb_hub_remove_port_device(struct usb_hub *hub, int port1) +{ +	struct usb_port *port_dev = hub->ports[port1 - 1]; +	struct usb_port *peer; + +	peer = port_dev->peer; +	if (peer) +		unlink_peers(port_dev, peer); +	device_unregister(&port_dev->dev); +} diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 25719da45e3..739ee8e8bdf 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -13,19 +13,25 @@  #include <linux/usb.h>  #include <linux/usb/quirks.h> +#include <linux/usb/hcd.h>  #include "usb.h" -/* List of quirky USB devices.  Please keep this list ordered by: +/* Lists of quirky USB devices, split in device quirks and interface quirks. + * Device quirks are applied at the very beginning of the enumeration process, + * right after reading the device descriptor. They can thus only match on device + * information. + * + * Interface quirks are applied after reading all the configuration descriptors. + * They can match on both device and interface information. + * + * Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as + * interface quirks, as they only influence the enumeration process which is run + * before processing the interface quirks. + * + * Please keep the lists ordered by:   * 	1) Vendor ID   * 	2) Product ID   * 	3) Class ID - * - * as we want specific devices to be overridden first, and only after that, any - * class specific quirks. - * - * Right now the logic aborts if it finds a valid device in the table, we might - * want to change that in the future if it turns out that a whole class of - * devices is broken...   */  static const struct usb_device_id usb_quirk_list[] = {  	/* CBM - Flash disk */ @@ -38,6 +44,31 @@ static const struct usb_device_id usb_quirk_list[] = {  	/* Creative SB Audigy 2 NX */  	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Microsoft LifeCam-VX700 v2.0 */ +	{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech HD Pro Webcams C920 and C930e */ +	{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, +	{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, + +	/* Logitech Quickcam Fusion */ +	{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam Orbit MP */ +	{ USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam Pro for Notebook */ +	{ USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam Pro 5000 */ +	{ USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam OEM Dell Notebook */ +	{ USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam OEM Cisco VT Camera II */ +	{ USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Logitech Harmony 700-series */  	{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, @@ -48,12 +79,29 @@ static const struct usb_device_id usb_quirk_list[] = {  	{ USB_DEVICE(0x04b4, 0x0526), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, +	/* Microchip Joss Optical infrared touchboard device */ +	{ USB_DEVICE(0x04d8, 0x000c), .driver_info = +			USB_QUIRK_CONFIG_INTF_STRINGS }, + +	/* CarrolTouch 4000U */ +	{ USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* CarrolTouch 4500U */ +	{ USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Samsung Android phone modem - ID conflict with SPH-I500 */ +	{ USB_DEVICE(0x04e8, 0x6601), .driver_info = +			USB_QUIRK_CONFIG_INTF_STRINGS }, +  	/* Roland SC-8820 */  	{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },  	/* Edirol SD-20 */  	{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Alcor Micro Corp. Hub */ +	{ USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* appletouch */  	{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, @@ -65,15 +113,31 @@ static const struct usb_device_id usb_quirk_list[] = {  	{ USB_DEVICE(0x06a3, 0x0006), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, +	/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */ +	{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Guillemot Webcam Hercules Dualpix Exchange*/ +	{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Midiman M-Audio Keystation 88es */ +	{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* M-Systems Flash Disk Pioneers */  	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Keytouch QWERTY Panel keyboard */ +	{ USB_DEVICE(0x0926, 0x3333), .driver_info = +			USB_QUIRK_CONFIG_INTF_STRINGS }, +  	/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */  	{ USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },  	/* Broadcom BCM92035DGROM BT dongle */  	{ USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* MAYA44USB sound device */ +	{ USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Action Semiconductor flash disk */  	{ USB_DEVICE(0x10d6, 0x2200), .driver_info =  			USB_QUIRK_STRING_FETCH_255 }, @@ -91,16 +155,84 @@ static const struct usb_device_id usb_quirk_list[] = {  	{ }  /* terminating entry must be last */  }; -static const struct usb_device_id *find_id(struct usb_device *udev) +static const struct usb_device_id usb_interface_quirk_list[] = { +	/* Logitech UVC Cameras */ +	{ USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0), +	  .driver_info = USB_QUIRK_RESET_RESUME }, + +	{ }  /* terminating entry must be last */ +}; + +static const struct usb_device_id usb_amd_resume_quirk_list[] = { +	/* Lenovo Mouse with Pixart controller */ +	{ USB_DEVICE(0x17ef, 0x602e), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Pixart Mouse */ +	{ USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME }, +	{ USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME }, +	{ USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Optical Mouse M90/M100 */ +	{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME }, + +	{ }  /* terminating entry must be last */ +}; + +static bool usb_match_any_interface(struct usb_device *udev, +				    const struct usb_device_id *id) +{ +	unsigned int i; + +	for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) { +		struct usb_host_config *cfg = &udev->config[i]; +		unsigned int j; + +		for (j = 0; j < cfg->desc.bNumInterfaces; ++j) { +			struct usb_interface_cache *cache; +			struct usb_host_interface *intf; + +			cache = cfg->intf_cache[j]; +			if (cache->num_altsetting == 0) +				continue; + +			intf = &cache->altsetting[0]; +			if (usb_match_one_id_intf(udev, intf, id)) +				return true; +		} +	} + +	return false; +} + +static int usb_amd_resume_quirk(struct usb_device *udev)  { -	const struct usb_device_id *id = usb_quirk_list; +	struct usb_hcd *hcd; + +	hcd = bus_to_hcd(udev->bus); +	/* The device should be attached directly to root hub */ +	if (udev->level == 1 && hcd->amd_resume_bug == 1) +		return 1; -	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || -			id->driver_info; id++) { -		if (usb_match_device(udev, id)) -			return id; +	return 0; +} + +static u32 __usb_detect_quirks(struct usb_device *udev, +			       const struct usb_device_id *id) +{ +	u32 quirks = 0; + +	for (; id->match_flags; id++) { +		if (!usb_match_device(udev, id)) +			continue; + +		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) && +		    !usb_match_any_interface(udev, id)) +			continue; + +		quirks |= (u32)(id->driver_info);  	} -	return NULL; + +	return quirks;  }  /* @@ -108,42 +240,39 @@ static const struct usb_device_id *find_id(struct usb_device *udev)   */  void usb_detect_quirks(struct usb_device *udev)  { -	const struct usb_device_id *id = usb_quirk_list; +	udev->quirks = __usb_detect_quirks(udev, usb_quirk_list); -	id = find_id(udev); -	if (id) -		udev->quirks = (u32)(id->driver_info); -	if (udev->quirks) -		dev_dbg(&udev->dev, "USB quirks for this device: %x\n", -				udev->quirks); - -#ifdef	CONFIG_USB_SUSPEND - -	/* By default, disable autosuspend for all devices.  The hub driver -	 * will enable it for hubs. +	/* +	 * Pixart-based mice would trigger remote wakeup issue on AMD +	 * Yangtze chipset, so set them as RESET_RESUME flag.  	 */ -	usb_disable_autosuspend(udev); +	if (usb_amd_resume_quirk(udev)) +		udev->quirks |= __usb_detect_quirks(udev, +				usb_amd_resume_quirk_list); -	/* Autosuspend can also be disabled if the initial autosuspend_delay -	 * is negative. -	 */ -	if (udev->autosuspend_delay < 0) -		usb_autoresume_device(udev); - -#endif +	if (udev->quirks) +		dev_dbg(&udev->dev, "USB quirks for this device: %x\n", +			udev->quirks); -	/* For the present, all devices default to USB-PERSIST enabled */ -#if 0		/* was: #ifdef CONFIG_PM */ +#ifdef CONFIG_USB_DEFAULT_PERSIST +	if (!(udev->quirks & USB_QUIRK_RESET)) +		udev->persist_enabled = 1; +#else  	/* Hubs are automatically enabled for USB-PERSIST */  	if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)  		udev->persist_enabled = 1; +#endif	/* CONFIG_USB_DEFAULT_PERSIST */ +} -#else -	/* In the absence of PM, we can safely enable USB-PERSIST -	 * for all devices.  It will affect things like hub resets -	 * and EMF-related port disables. -	 */ -	if (!(udev->quirks & USB_QUIRK_RESET_MORPHS)) -		udev->persist_enabled = 1; -#endif	/* CONFIG_PM */ +void usb_detect_interface_quirks(struct usb_device *udev) +{ +	u32 quirks; + +	quirks = __usb_detect_quirks(udev, usb_interface_quirk_list); +	if (quirks == 0) +		return; + +	dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n", +		quirks); +	udev->quirks |= quirks;  } diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 448f5b47fc4..1236c6011c7 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -17,50 +17,71 @@  #include "usb.h"  /* Active configuration fields */ -#define usb_actconfig_show(field, multiplier, format_string)		\ -static ssize_t  show_##field(struct device *dev,			\ -		struct device_attribute *attr, char *buf)		\ +#define usb_actconfig_show(field, format_string)			\ +static ssize_t field##_show(struct device *dev,				\ +			    struct device_attribute *attr, char *buf)	\  {									\  	struct usb_device *udev;					\  	struct usb_host_config *actconfig;				\ +	ssize_t rc = 0;							\  									\  	udev = to_usb_device(dev);					\ +	usb_lock_device(udev);						\  	actconfig = udev->actconfig;					\  	if (actconfig)							\ -		return sprintf(buf, format_string,			\ -				actconfig->desc.field * multiplier);	\ -	else								\ -		return 0;						\ +		rc = sprintf(buf, format_string,			\ +				actconfig->desc.field);			\ +	usb_unlock_device(udev);					\ +	return rc;							\  }									\ -#define usb_actconfig_attr(field, multiplier, format_string)		\ -usb_actconfig_show(field, multiplier, format_string)			\ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); +#define usb_actconfig_attr(field, format_string)		\ +	usb_actconfig_show(field, format_string)		\ +	static DEVICE_ATTR_RO(field) -usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") -usb_actconfig_attr(bmAttributes, 1, "%2x\n") -usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") +usb_actconfig_attr(bNumInterfaces, "%2d\n"); +usb_actconfig_attr(bmAttributes, "%2x\n"); -static ssize_t show_configuration_string(struct device *dev, +static ssize_t bMaxPower_show(struct device *dev,  		struct device_attribute *attr, char *buf)  {  	struct usb_device *udev;  	struct usb_host_config *actconfig; +	ssize_t rc = 0;  	udev = to_usb_device(dev); +	usb_lock_device(udev);  	actconfig = udev->actconfig; -	if ((!actconfig) || (!actconfig->string)) -		return 0; -	return sprintf(buf, "%s\n", actconfig->string); +	if (actconfig) +		rc = sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig)); +	usb_unlock_device(udev); +	return rc;  } -static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); +static DEVICE_ATTR_RO(bMaxPower); + +static ssize_t configuration_show(struct device *dev, +		struct device_attribute *attr, char *buf) +{ +	struct usb_device *udev; +	struct usb_host_config *actconfig; +	ssize_t rc = 0; + +	udev = to_usb_device(dev); +	usb_lock_device(udev); +	actconfig = udev->actconfig; +	if (actconfig && actconfig->string) +		rc = sprintf(buf, "%s\n", actconfig->string); +	usb_unlock_device(udev); +	return rc; +} +static DEVICE_ATTR_RO(configuration);  /* configuration value is always present, and r/w */ -usb_actconfig_show(bConfigurationValue, 1, "%u\n"); +usb_actconfig_show(bConfigurationValue, "%u\n"); -static ssize_t -set_bConfigurationValue(struct device *dev, struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t bConfigurationValue_store(struct device *dev, +					 struct device_attribute *attr, +					 const char *buf, size_t count)  {  	struct usb_device	*udev = to_usb_device(dev);  	int			config, value; @@ -72,13 +93,12 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr,  	usb_unlock_device(udev);  	return (value < 0) ? value : count;  } - -static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, -		show_bConfigurationValue, set_bConfigurationValue); +static DEVICE_ATTR_IGNORE_LOCKDEP(bConfigurationValue, S_IRUGO | S_IWUSR, +		bConfigurationValue_show, bConfigurationValue_store);  /* String fields */  #define usb_string_attr(name)						\ -static ssize_t  show_##name(struct device *dev,				\ +static ssize_t  name##_show(struct device *dev,				\  		struct device_attribute *attr, char *buf)		\  {									\  	struct usb_device *udev;					\ @@ -90,14 +110,14 @@ static ssize_t  show_##name(struct device *dev,				\  	usb_unlock_device(udev);					\  	return retval;							\  }									\ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); +static DEVICE_ATTR_RO(name)  usb_string_attr(product);  usb_string_attr(manufacturer);  usb_string_attr(serial); -static ssize_t -show_speed(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t speed_show(struct device *dev, struct device_attribute *attr, +			  char *buf)  {  	struct usb_device *udev;  	char *speed; @@ -126,40 +146,40 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)  	}  	return sprintf(buf, "%s\n", speed);  } -static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); +static DEVICE_ATTR_RO(speed); -static ssize_t -show_busnum(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t busnum_show(struct device *dev, struct device_attribute *attr, +			   char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "%d\n", udev->bus->busnum);  } -static DEVICE_ATTR(busnum, S_IRUGO, show_busnum, NULL); +static DEVICE_ATTR_RO(busnum); -static ssize_t -show_devnum(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t devnum_show(struct device *dev, struct device_attribute *attr, +			   char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "%d\n", udev->devnum);  } -static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); +static DEVICE_ATTR_RO(devnum); -static ssize_t -show_devpath(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t devpath_show(struct device *dev, struct device_attribute *attr, +			    char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "%s\n", udev->devpath);  } -static DEVICE_ATTR(devpath, S_IRUGO, show_devpath, NULL); +static DEVICE_ATTR_RO(devpath); -static ssize_t -show_version(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t version_show(struct device *dev, struct device_attribute *attr, +			    char *buf)  {  	struct usb_device *udev;  	u16 bcdUSB; @@ -168,84 +188,110 @@ show_version(struct device *dev, struct device_attribute *attr, char *buf)  	bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB);  	return sprintf(buf, "%2x.%02x\n", bcdUSB >> 8, bcdUSB & 0xff);  } -static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); +static DEVICE_ATTR_RO(version); -static ssize_t -show_maxchild(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t maxchild_show(struct device *dev, struct device_attribute *attr, +			     char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "%d\n", udev->maxchild);  } -static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); +static DEVICE_ATTR_RO(maxchild); -static ssize_t -show_quirks(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t quirks_show(struct device *dev, struct device_attribute *attr, +			   char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "0x%x\n", udev->quirks);  } -static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); +static DEVICE_ATTR_RO(quirks); -static ssize_t -show_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t avoid_reset_quirk_show(struct device *dev, +				      struct device_attribute *attr, char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev); -	return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET_MORPHS)); +	return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET));  } -static ssize_t -set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t avoid_reset_quirk_store(struct device *dev, +				      struct device_attribute *attr, +				      const char *buf, size_t count)  {  	struct usb_device	*udev = to_usb_device(dev); -	int			config; +	int			val; -	if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1) +	if (sscanf(buf, "%d", &val) != 1 || val < 0 || val > 1)  		return -EINVAL;  	usb_lock_device(udev); -	if (config) -		udev->quirks |= USB_QUIRK_RESET_MORPHS; +	if (val) +		udev->quirks |= USB_QUIRK_RESET;  	else -		udev->quirks &= ~USB_QUIRK_RESET_MORPHS; +		udev->quirks &= ~USB_QUIRK_RESET;  	usb_unlock_device(udev);  	return count;  } +static DEVICE_ATTR_RW(avoid_reset_quirk); -static DEVICE_ATTR(avoid_reset_quirk, S_IRUGO | S_IWUSR, -		show_avoid_reset_quirk, set_avoid_reset_quirk); - -static ssize_t -show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t urbnum_show(struct device *dev, struct device_attribute *attr, +			   char *buf)  {  	struct usb_device *udev;  	udev = to_usb_device(dev);  	return sprintf(buf, "%d\n", atomic_read(&udev->urbnum));  } -static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); +static DEVICE_ATTR_RO(urbnum); +static ssize_t removable_show(struct device *dev, struct device_attribute *attr, +			      char *buf) +{ +	struct usb_device *udev; +	char *state; -#ifdef	CONFIG_PM +	udev = to_usb_device(dev); -static const char power_group[] = "power"; +	switch (udev->removable) { +	case USB_DEVICE_REMOVABLE: +		state = "removable"; +		break; +	case USB_DEVICE_FIXED: +		state = "fixed"; +		break; +	default: +		state = "unknown"; +	} -static ssize_t -show_persist(struct device *dev, struct device_attribute *attr, char *buf) +	return sprintf(buf, "%s\n", state); +} +static DEVICE_ATTR_RO(removable); + +static ssize_t ltm_capable_show(struct device *dev, +				struct device_attribute *attr, char *buf) +{ +	if (usb_device_supports_ltm(to_usb_device(dev))) +		return sprintf(buf, "%s\n", "yes"); +	return sprintf(buf, "%s\n", "no"); +} +static DEVICE_ATTR_RO(ltm_capable); + +#ifdef	CONFIG_PM + +static ssize_t persist_show(struct device *dev, struct device_attribute *attr, +			    char *buf)  {  	struct usb_device *udev = to_usb_device(dev);  	return sprintf(buf, "%d\n", udev->persist_enabled);  } -static ssize_t -set_persist(struct device *dev, struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t persist_store(struct device *dev, struct device_attribute *attr, +			     const char *buf, size_t count)  {  	struct usb_device *udev = to_usb_device(dev);  	int value; @@ -262,8 +308,7 @@ set_persist(struct device *dev, struct device_attribute *attr,  	usb_unlock_device(udev);  	return count;  } - -static DEVICE_ATTR(persist, S_IRUGO | S_IWUSR, show_persist, set_persist); +static DEVICE_ATTR_RW(persist);  static int add_persist_attributes(struct device *dev)  { @@ -278,7 +323,7 @@ static int add_persist_attributes(struct device *dev)  		if (udev->descriptor.bDeviceClass != USB_CLASS_HUB)  			rc = sysfs_add_file_to_group(&dev->kobj,  					&dev_attr_persist.attr, -					power_group); +					power_group_name);  	}  	return rc;  } @@ -287,7 +332,7 @@ static void remove_persist_attributes(struct device *dev)  {  	sysfs_remove_file_from_group(&dev->kobj,  			&dev_attr_persist.attr, -			power_group); +			power_group_name);  }  #else @@ -296,19 +341,17 @@ static void remove_persist_attributes(struct device *dev)  #endif	/* CONFIG_PM */ -#ifdef	CONFIG_USB_SUSPEND +#ifdef	CONFIG_PM_RUNTIME -static ssize_t -show_connected_duration(struct device *dev, struct device_attribute *attr, -		char *buf) +static ssize_t connected_duration_show(struct device *dev, +				       struct device_attribute *attr, char *buf)  {  	struct usb_device *udev = to_usb_device(dev);  	return sprintf(buf, "%u\n",  			jiffies_to_msecs(jiffies - udev->connect_time));  } - -static DEVICE_ATTR(connected_duration, S_IRUGO, show_connected_duration, NULL); +static DEVICE_ATTR_RO(connected_duration);  /*   * If the device is resumed, the last time the device was suspended has @@ -317,9 +360,8 @@ static DEVICE_ATTR(connected_duration, S_IRUGO, show_connected_duration, NULL);   *   * If the device is suspended, the active_duration is up-to-date.   */ -static ssize_t -show_active_duration(struct device *dev, struct device_attribute *attr, -		char *buf) +static ssize_t active_duration_show(struct device *dev, +				    struct device_attribute *attr, char *buf)  {  	struct usb_device *udev = to_usb_device(dev);  	int duration; @@ -330,60 +372,34 @@ show_active_duration(struct device *dev, struct device_attribute *attr,  		duration = jiffies_to_msecs(udev->active_duration);  	return sprintf(buf, "%u\n", duration);  } +static DEVICE_ATTR_RO(active_duration); -static DEVICE_ATTR(active_duration, S_IRUGO, show_active_duration, NULL); - -static ssize_t -show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t autosuspend_show(struct device *dev, +				struct device_attribute *attr, char *buf)  { -	struct usb_device *udev = to_usb_device(dev); - -	return sprintf(buf, "%d\n", udev->autosuspend_delay / HZ); +	return sprintf(buf, "%d\n", dev->power.autosuspend_delay / 1000);  } -static ssize_t -set_autosuspend(struct device *dev, struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t autosuspend_store(struct device *dev, +				 struct device_attribute *attr, const char *buf, +				 size_t count)  { -	struct usb_device *udev = to_usb_device(dev); -	int value, old_delay; -	int rc; +	int value; -	if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || -			value <= - INT_MAX/HZ) +	if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/1000 || +			value <= -INT_MAX/1000)  		return -EINVAL; -	value *= HZ; - -	usb_lock_device(udev); -	old_delay = udev->autosuspend_delay; -	udev->autosuspend_delay = value; - -	if (old_delay < 0) {	/* Autosuspend wasn't allowed */ -		if (value >= 0) -			usb_autosuspend_device(udev); -	} else {		/* Autosuspend was allowed */ -		if (value < 0) { -			rc = usb_autoresume_device(udev); -			if (rc < 0) { -				count = rc; -				udev->autosuspend_delay = old_delay; -			} -		} else { -			usb_try_autosuspend_device(udev); -		} -	} -	usb_unlock_device(udev); +	pm_runtime_set_autosuspend_delay(dev, value * 1000);  	return count;  } - -static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, -		show_autosuspend, set_autosuspend); +static DEVICE_ATTR_RW(autosuspend);  static const char on_string[] = "on";  static const char auto_string[] = "auto"; -static void warn_level(void) { +static void warn_level(void) +{  	static int level_warned;  	if (!level_warned) { @@ -393,8 +409,8 @@ static void warn_level(void) {  	}  } -static ssize_t -show_level(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t level_show(struct device *dev, struct device_attribute *attr, +			  char *buf)  {  	struct usb_device *udev = to_usb_device(dev);  	const char *p = auto_string; @@ -405,9 +421,8 @@ show_level(struct device *dev, struct device_attribute *attr, char *buf)  	return sprintf(buf, "%s\n", p);  } -static ssize_t -set_level(struct device *dev, struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t level_store(struct device *dev, struct device_attribute *attr, +			   const char *buf, size_t count)  {  	struct usb_device *udev = to_usb_device(dev);  	int len = count; @@ -435,47 +450,137 @@ set_level(struct device *dev, struct device_attribute *attr,  	usb_unlock_device(udev);  	return rc;  } +static DEVICE_ATTR_RW(level); + +static ssize_t usb2_hardware_lpm_show(struct device *dev, +				      struct device_attribute *attr, char *buf) +{ +	struct usb_device *udev = to_usb_device(dev); +	const char *p; -static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); +	if (udev->usb2_hw_lpm_allowed == 1) +		p = "enabled"; +	else +		p = "disabled"; + +	return sprintf(buf, "%s\n", p); +} + +static ssize_t usb2_hardware_lpm_store(struct device *dev, +				       struct device_attribute *attr, +				       const char *buf, size_t count) +{ +	struct usb_device *udev = to_usb_device(dev); +	bool value; +	int ret; + +	usb_lock_device(udev); + +	ret = strtobool(buf, &value); + +	if (!ret) { +		udev->usb2_hw_lpm_allowed = value; +		ret = usb_set_usb2_hardware_lpm(udev, value); +	} + +	usb_unlock_device(udev); + +	if (!ret) +		return count; + +	return ret; +} +static DEVICE_ATTR_RW(usb2_hardware_lpm); + +static ssize_t usb2_lpm_l1_timeout_show(struct device *dev, +					struct device_attribute *attr, +					char *buf) +{ +	struct usb_device *udev = to_usb_device(dev); +	return sprintf(buf, "%d\n", udev->l1_params.timeout); +} + +static ssize_t usb2_lpm_l1_timeout_store(struct device *dev, +					 struct device_attribute *attr, +					 const char *buf, size_t count) +{ +	struct usb_device *udev = to_usb_device(dev); +	u16 timeout; + +	if (kstrtou16(buf, 0, &timeout)) +		return -EINVAL; + +	udev->l1_params.timeout = timeout; + +	return count; +} +static DEVICE_ATTR_RW(usb2_lpm_l1_timeout); + +static ssize_t usb2_lpm_besl_show(struct device *dev, +				  struct device_attribute *attr, char *buf) +{ +	struct usb_device *udev = to_usb_device(dev); +	return sprintf(buf, "%d\n", udev->l1_params.besl); +} + +static ssize_t usb2_lpm_besl_store(struct device *dev, +				   struct device_attribute *attr, +				   const char *buf, size_t count) +{ +	struct usb_device *udev = to_usb_device(dev); +	u8 besl; + +	if (kstrtou8(buf, 0, &besl) || besl > 15) +		return -EINVAL; + +	udev->l1_params.besl = besl; + +	return count; +} +static DEVICE_ATTR_RW(usb2_lpm_besl); + +static struct attribute *usb2_hardware_lpm_attr[] = { +	&dev_attr_usb2_hardware_lpm.attr, +	&dev_attr_usb2_lpm_l1_timeout.attr, +	&dev_attr_usb2_lpm_besl.attr, +	NULL, +}; +static struct attribute_group usb2_hardware_lpm_attr_group = { +	.name	= power_group_name, +	.attrs	= usb2_hardware_lpm_attr, +}; + +static struct attribute *power_attrs[] = { +	&dev_attr_autosuspend.attr, +	&dev_attr_level.attr, +	&dev_attr_connected_duration.attr, +	&dev_attr_active_duration.attr, +	NULL, +}; +static struct attribute_group power_attr_group = { +	.name	= power_group_name, +	.attrs	= power_attrs, +};  static int add_power_attributes(struct device *dev)  {  	int rc = 0;  	if (is_usb_device(dev)) { -		rc = sysfs_add_file_to_group(&dev->kobj, -				&dev_attr_autosuspend.attr, -				power_group); -		if (rc == 0) -			rc = sysfs_add_file_to_group(&dev->kobj, -					&dev_attr_level.attr, -					power_group); -		if (rc == 0) -			rc = sysfs_add_file_to_group(&dev->kobj, -					&dev_attr_connected_duration.attr, -					power_group); -		if (rc == 0) -			rc = sysfs_add_file_to_group(&dev->kobj, -					&dev_attr_active_duration.attr, -					power_group); +		struct usb_device *udev = to_usb_device(dev); +		rc = sysfs_merge_group(&dev->kobj, &power_attr_group); +		if (udev->usb2_hw_lpm_capable == 1) +			rc = sysfs_merge_group(&dev->kobj, +					&usb2_hardware_lpm_attr_group);  	} +  	return rc;  }  static void remove_power_attributes(struct device *dev)  { -	sysfs_remove_file_from_group(&dev->kobj, -			&dev_attr_active_duration.attr, -			power_group); -	sysfs_remove_file_from_group(&dev->kobj, -			&dev_attr_connected_duration.attr, -			power_group); -	sysfs_remove_file_from_group(&dev->kobj, -			&dev_attr_level.attr, -			power_group); -	sysfs_remove_file_from_group(&dev->kobj, -			&dev_attr_autosuspend.attr, -			power_group); +	sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); +	sysfs_unmerge_group(&dev->kobj, &power_attr_group);  }  #else @@ -483,13 +588,13 @@ static void remove_power_attributes(struct device *dev)  #define add_power_attributes(dev)	0  #define remove_power_attributes(dev)	do {} while (0) -#endif	/* CONFIG_USB_SUSPEND */ +#endif	/* CONFIG_PM_RUNTIME */  /* Descriptor fields */  #define usb_descriptor_attr_le16(field, format_string)			\  static ssize_t								\ -show_##field(struct device *dev, struct device_attribute *attr,	\ +field##_show(struct device *dev, struct device_attribute *attr,	\  		char *buf)						\  {									\  	struct usb_device *udev;					\ @@ -498,15 +603,15 @@ show_##field(struct device *dev, struct device_attribute *attr,	\  	return sprintf(buf, format_string, 				\  			le16_to_cpu(udev->descriptor.field));		\  }									\ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); +static DEVICE_ATTR_RO(field) -usb_descriptor_attr_le16(idVendor, "%04x\n") -usb_descriptor_attr_le16(idProduct, "%04x\n") -usb_descriptor_attr_le16(bcdDevice, "%04x\n") +usb_descriptor_attr_le16(idVendor, "%04x\n"); +usb_descriptor_attr_le16(idProduct, "%04x\n"); +usb_descriptor_attr_le16(bcdDevice, "%04x\n");  #define usb_descriptor_attr(field, format_string)			\  static ssize_t								\ -show_##field(struct device *dev, struct device_attribute *attr,	\ +field##_show(struct device *dev, struct device_attribute *attr,	\  		char *buf)						\  {									\  	struct usb_device *udev;					\ @@ -514,34 +619,31 @@ show_##field(struct device *dev, struct device_attribute *attr,	\  	udev = to_usb_device(dev);					\  	return sprintf(buf, format_string, udev->descriptor.field);	\  }									\ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); - -usb_descriptor_attr(bDeviceClass, "%02x\n") -usb_descriptor_attr(bDeviceSubClass, "%02x\n") -usb_descriptor_attr(bDeviceProtocol, "%02x\n") -usb_descriptor_attr(bNumConfigurations, "%d\n") -usb_descriptor_attr(bMaxPacketSize0, "%d\n") +static DEVICE_ATTR_RO(field) +usb_descriptor_attr(bDeviceClass, "%02x\n"); +usb_descriptor_attr(bDeviceSubClass, "%02x\n"); +usb_descriptor_attr(bDeviceProtocol, "%02x\n"); +usb_descriptor_attr(bNumConfigurations, "%d\n"); +usb_descriptor_attr(bMaxPacketSize0, "%d\n");  /* show if the device is authorized (1) or not (0) */ -static ssize_t usb_dev_authorized_show(struct device *dev, -				       struct device_attribute *attr, -				       char *buf) +static ssize_t authorized_show(struct device *dev, +			       struct device_attribute *attr, char *buf)  {  	struct usb_device *usb_dev = to_usb_device(dev);  	return snprintf(buf, PAGE_SIZE, "%u\n", usb_dev->authorized);  } -  /*   * Authorize a device to be used in the system   *   * Writing a 0 deauthorizes the device, writing a 1 authorizes it.   */ -static ssize_t usb_dev_authorized_store(struct device *dev, -					struct device_attribute *attr, -					const char *buf, size_t size) +static ssize_t authorized_store(struct device *dev, +				struct device_attribute *attr, const char *buf, +				size_t size)  {  	ssize_t result;  	struct usb_device *usb_dev = to_usb_device(dev); @@ -553,16 +655,14 @@ static ssize_t usb_dev_authorized_store(struct device *dev,  		result = usb_deauthorize_device(usb_dev);  	else  		result = usb_authorize_device(usb_dev); -	return result < 0? result : size; +	return result < 0 ? result : size;  } - -static DEVICE_ATTR(authorized, 0644, -	    usb_dev_authorized_show, usb_dev_authorized_store); +static DEVICE_ATTR_IGNORE_LOCKDEP(authorized, S_IRUGO | S_IWUSR, +				  authorized_show, authorized_store);  /* "Safely remove a device" */ -static ssize_t usb_remove_store(struct device *dev, -		struct device_attribute *attr, -		const char *buf, size_t count) +static ssize_t remove_store(struct device *dev, struct device_attribute *attr, +			    const char *buf, size_t count)  {  	struct usb_device *udev = to_usb_device(dev);  	int rc = 0; @@ -579,7 +679,7 @@ static ssize_t usb_remove_store(struct device *dev,  	usb_unlock_device(udev);  	return rc;  } -static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store); +static DEVICE_ATTR_IGNORE_LOCKDEP(remove, S_IWUSR, NULL, remove_store);  static struct attribute *dev_attrs[] = { @@ -609,6 +709,8 @@ static struct attribute *dev_attrs[] = {  	&dev_attr_avoid_reset_quirk.attr,  	&dev_attr_authorized.attr,  	&dev_attr_remove.attr, +	&dev_attr_removable.attr, +	&dev_attr_ltm_capable.attr,  	NULL,  };  static struct attribute_group dev_attr_grp = { @@ -625,7 +727,7 @@ static struct attribute *dev_string_attrs[] = {  	NULL  }; -static mode_t dev_string_attrs_are_visible(struct kobject *kobj, +static umode_t dev_string_attrs_are_visible(struct kobject *kobj,  		struct attribute *a, int n)  {  	struct device *dev = container_of(kobj, struct device, kobj); @@ -673,6 +775,7 @@ read_descriptors(struct file *filp, struct kobject *kobj,  	 * Following that are the raw descriptor entries for all the  	 * configurations (config plus subsidiary descriptors).  	 */ +	usb_lock_device(udev);  	for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations &&  			nleft > 0; ++cfgno) {  		if (cfgno < 0) { @@ -693,6 +796,7 @@ read_descriptors(struct file *filp, struct kobject *kobj,  			off -= srclen;  		}  	} +	usb_unlock_device(udev);  	return count - nleft;  } @@ -733,10 +837,10 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)  	device_remove_bin_file(dev, &dev_bin_attr_descriptors);  } -/* Interface Accociation Descriptor fields */ +/* Interface Association Descriptor fields */  #define usb_intf_assoc_attr(field, format_string)			\  static ssize_t								\ -show_iad_##field(struct device *dev, struct device_attribute *attr,	\ +iad_##field##_show(struct device *dev, struct device_attribute *attr,	\  		char *buf)						\  {									\  	struct usb_interface *intf = to_usb_interface(dev);		\ @@ -744,18 +848,18 @@ show_iad_##field(struct device *dev, struct device_attribute *attr,	\  	return sprintf(buf, format_string,				\  			intf->intf_assoc->field); 			\  }									\ -static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL); +static DEVICE_ATTR_RO(iad_##field) -usb_intf_assoc_attr(bFirstInterface, "%02x\n") -usb_intf_assoc_attr(bInterfaceCount, "%02d\n") -usb_intf_assoc_attr(bFunctionClass, "%02x\n") -usb_intf_assoc_attr(bFunctionSubClass, "%02x\n") -usb_intf_assoc_attr(bFunctionProtocol, "%02x\n") +usb_intf_assoc_attr(bFirstInterface, "%02x\n"); +usb_intf_assoc_attr(bInterfaceCount, "%02d\n"); +usb_intf_assoc_attr(bFunctionClass, "%02x\n"); +usb_intf_assoc_attr(bFunctionSubClass, "%02x\n"); +usb_intf_assoc_attr(bFunctionProtocol, "%02x\n");  /* Interface fields */  #define usb_intf_attr(field, format_string)				\  static ssize_t								\ -show_##field(struct device *dev, struct device_attribute *attr,	\ +field##_show(struct device *dev, struct device_attribute *attr,		\  		char *buf)						\  {									\  	struct usb_interface *intf = to_usb_interface(dev);		\ @@ -763,33 +867,31 @@ show_##field(struct device *dev, struct device_attribute *attr,	\  	return sprintf(buf, format_string,				\  			intf->cur_altsetting->desc.field); 		\  }									\ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); +static DEVICE_ATTR_RO(field) -usb_intf_attr(bInterfaceNumber, "%02x\n") -usb_intf_attr(bAlternateSetting, "%2d\n") -usb_intf_attr(bNumEndpoints, "%02x\n") -usb_intf_attr(bInterfaceClass, "%02x\n") -usb_intf_attr(bInterfaceSubClass, "%02x\n") -usb_intf_attr(bInterfaceProtocol, "%02x\n") +usb_intf_attr(bInterfaceNumber, "%02x\n"); +usb_intf_attr(bAlternateSetting, "%2d\n"); +usb_intf_attr(bNumEndpoints, "%02x\n"); +usb_intf_attr(bInterfaceClass, "%02x\n"); +usb_intf_attr(bInterfaceSubClass, "%02x\n"); +usb_intf_attr(bInterfaceProtocol, "%02x\n"); -static ssize_t show_interface_string(struct device *dev, -		struct device_attribute *attr, char *buf) +static ssize_t interface_show(struct device *dev, struct device_attribute *attr, +			      char *buf)  {  	struct usb_interface *intf;  	char *string;  	intf = to_usb_interface(dev); -	string = intf->cur_altsetting->string; -	barrier();		/* The altsetting might change! */ - +	string = ACCESS_ONCE(intf->cur_altsetting->string);  	if (!string)  		return 0;  	return sprintf(buf, "%s\n", string);  } -static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); +static DEVICE_ATTR_RO(interface); -static ssize_t show_modalias(struct device *dev, -		struct device_attribute *attr, char *buf) +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, +			     char *buf)  {  	struct usb_interface *intf;  	struct usb_device *udev; @@ -797,10 +899,10 @@ static ssize_t show_modalias(struct device *dev,  	intf = to_usb_interface(dev);  	udev = interface_to_usbdev(intf); -	alt = intf->cur_altsetting; +	alt = ACCESS_ONCE(intf->cur_altsetting);  	return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" -			"ic%02Xisc%02Xip%02X\n", +			"ic%02Xisc%02Xip%02Xin%02X\n",  			le16_to_cpu(udev->descriptor.idVendor),  			le16_to_cpu(udev->descriptor.idProduct),  			le16_to_cpu(udev->descriptor.bcdDevice), @@ -809,32 +911,25 @@ static ssize_t show_modalias(struct device *dev,  			udev->descriptor.bDeviceProtocol,  			alt->desc.bInterfaceClass,  			alt->desc.bInterfaceSubClass, -			alt->desc.bInterfaceProtocol); +			alt->desc.bInterfaceProtocol, +			alt->desc.bInterfaceNumber);  } -static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); +static DEVICE_ATTR_RO(modalias); -static ssize_t show_supports_autosuspend(struct device *dev, -		struct device_attribute *attr, char *buf) +static ssize_t supports_autosuspend_show(struct device *dev, +					 struct device_attribute *attr, +					 char *buf)  { -	struct usb_interface *intf; -	struct usb_device *udev; -	int ret; +	int s; -	intf = to_usb_interface(dev); -	udev = interface_to_usbdev(intf); - -	usb_lock_device(udev); +	device_lock(dev);  	/* Devices will be autosuspended even when an interface isn't claimed */ -	if (!intf->dev.driver || -			to_usb_driver(intf->dev.driver)->supports_autosuspend) -		ret = sprintf(buf, "%u\n", 1); -	else -		ret = sprintf(buf, "%u\n", 0); -	usb_unlock_device(udev); +	s = (!dev->driver || to_usb_driver(dev->driver)->supports_autosuspend); +	device_unlock(dev); -	return ret; +	return sprintf(buf, "%u\n", s);  } -static DEVICE_ATTR(supports_autosuspend, S_IRUGO, show_supports_autosuspend, NULL); +static DEVICE_ATTR_RO(supports_autosuspend);  static struct attribute *intf_attrs[] = {  	&dev_attr_bInterfaceNumber.attr, @@ -860,7 +955,7 @@ static struct attribute *intf_assoc_attrs[] = {  	NULL,  }; -static mode_t intf_assoc_attrs_are_visible(struct kobject *kobj, +static umode_t intf_assoc_attrs_are_visible(struct kobject *kobj,  		struct attribute *a, int n)  {  	struct device *dev = container_of(kobj, struct device, kobj); @@ -882,22 +977,19 @@ const struct attribute_group *usb_interface_groups[] = {  	NULL  }; -int usb_create_sysfs_intf_files(struct usb_interface *intf) +void usb_create_sysfs_intf_files(struct usb_interface *intf)  {  	struct usb_device *udev = interface_to_usbdev(intf);  	struct usb_host_interface *alt = intf->cur_altsetting; -	int retval;  	if (intf->sysfs_files_created || intf->unregistering) -		return 0; +		return; -	if (alt->string == NULL && -			!(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) +	if (!alt->string && !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))  		alt->string = usb_cache_string(udev, alt->desc.iInterface); -	if (alt->string) -		retval = device_create_file(&intf->dev, &dev_attr_interface); +	if (alt->string && device_create_file(&intf->dev, &dev_attr_interface)) +		;	/* We don't actually care if the function fails. */  	intf->sysfs_files_created = 1; -	return 0;  }  void usb_remove_sysfs_intf_files(struct usb_interface *intf) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c14fc082864..991386ceb4e 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -2,11 +2,11 @@  #include <linux/string.h>  #include <linux/bitops.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/log2.h>  #include <linux/usb.h>  #include <linux/wait.h>  #include <linux/usb/hcd.h> +#include <linux/scatterlist.h>  #define to_urb(d) container_of(d, struct urb, kref) @@ -52,14 +52,14 @@ EXPORT_SYMBOL_GPL(usb_init_urb);   *	valid options for this.   *   * Creates an urb for the USB driver to use, initializes a few internal - * structures, incrementes the usage counter, and returns a pointer to it. - * - * If no memory is available, NULL is returned. + * structures, increments the usage counter, and returns a pointer to it.   *   * If the driver want to use this urb for interrupt, control, or bulk   * endpoints, pass '0' as the number of iso packets.   *   * The driver must call usb_free_urb() when it is finished with the urb. + * + * Return: A pointer to the new urb, or %NULL if no memory is available.   */  struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)  { @@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(usb_free_urb);   * host controller driver.  This allows proper reference counting to happen   * for urbs.   * - * A pointer to the urb with the incremented reference counter is returned. + * Return: A pointer to the urb with the incremented reference counter.   */  struct urb *usb_get_urb(struct urb *urb)  { @@ -137,13 +137,19 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)  }  EXPORT_SYMBOL_GPL(usb_anchor_urb); +static int usb_anchor_check_wakeup(struct usb_anchor *anchor) +{ +	return atomic_read(&anchor->suspend_wakeups) == 0 && +		list_empty(&anchor->urb_list); +} +  /* Callers must hold anchor->lock */  static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor)  {  	urb->anchor = NULL;  	list_del(&urb->anchor_list);  	usb_put_urb(urb); -	if (list_empty(&anchor->urb_list)) +	if (usb_anchor_check_wakeup(anchor))  		wake_up(&anchor->wait);  } @@ -199,13 +205,12 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);   * the particular kind of transfer, although they will not initialize   * any transfer flags.   * - * Successful submissions return 0; otherwise this routine returns a - * negative error number.  If the submission is successful, the complete() - * callback from the URB will be called exactly once, when the USB core and - * Host Controller Driver (HCD) are finished with the URB.  When the completion - * function is called, control of the URB is returned to the device - * driver which issued the request.  The completion handler may then - * immediately free or reuse that URB. + * If the submission is successful, the complete() callback from the URB + * will be called exactly once, when the USB core and Host Controller Driver + * (HCD) are finished with the URB.  When the completion function is called, + * control of the URB is returned to the device driver which issued the + * request.  The completion handler may then immediately free or reuse that + * URB.   *   * With few exceptions, USB device drivers should never access URB fields   * provided by usbcore or the HCD until its complete() is called. @@ -214,9 +219,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);   * urb->interval is modified to reflect the actual transfer period used   * (normally some power of two units).  And for isochronous urbs,   * urb->start_frame is modified to reflect when the URB's transfers were - * scheduled to start.  Not all isochronous transfer scheduling policies - * will work, but most host controller drivers should easily handle ISO - * queues going from now until 10-200 msec into the future. + * scheduled to start. + * + * Not all isochronous transfer scheduling policies will work, but most + * host controller drivers should easily handle ISO queues going from now + * until 10-200 msec into the future.  Drivers should try to keep at + * least one or two msec of data in the queue; many controllers require + * that new transfers start at least 1 msec in the future when they are + * added.  If the driver is unable to keep up and the queue empties out, + * the behavior for new submissions is governed by the URB_ISO_ASAP flag. + * If the flag is set, or if the queue is idle, then the URB is always + * assigned to the first available (and not yet expired) slot in the + * endpoint's schedule.  If the flag is not set and the queue is active + * then the URB is always assigned to the next slot in the schedule + * following the end of the endpoint's previous URB, even if that slot is + * in the past.  When a packet is assigned in this way to a slot that has + * already expired, the packet is not transmitted and the corresponding + * usb_iso_packet_descriptor's status field will return -EXDEV.  If this + * would happen to all the packets in the URB, submission fails with a + * -EXDEV error code.   *   * For control endpoints, the synchronous usb_control_msg() call is   * often used (in non-interrupt context) instead of this call. @@ -224,6 +245,9 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);   * that are standardized in the USB 2.0 specification.  For bulk   * endpoints, a synchronous usb_bulk_msg() call is available.   * + * Return: + * 0 on successful submissions. A negative error number otherwise. + *   * Request Queuing:   *   * URBs may be submitted to endpoints before previous ones complete, to @@ -256,7 +280,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);   *   * Device drivers must explicitly request that repetition, by ensuring that   * some URB is always on the endpoint's queue (except possibly for short - * periods during completion callacks).  When there is no longer an urb + * periods during completion callbacks).  When there is no longer an urb   * queued, the endpoint's bandwidth reservation is canceled.  This means   * drivers can use their completion handlers to ensure they keep bandwidth   * they need, by reinitializing and resubmitting the just-completed urb @@ -300,13 +324,22 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);   */  int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  { +	static int			pipetypes[4] = { +		PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT +	};  	int				xfertype, max;  	struct usb_device		*dev;  	struct usb_host_endpoint	*ep;  	int				is_out; +	unsigned int			allowed; -	if (!urb || urb->hcpriv || !urb->complete) +	if (!urb || !urb->complete)  		return -EINVAL; +	if (urb->hcpriv) { +		WARN_ONCE(1, "URB %p submitted while active\n", urb); +		return -EBUSY; +	} +  	dev = urb->dev;  	if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))  		return -ENODEV; @@ -350,7 +383,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  			dev->state < USB_STATE_CONFIGURED)  		return -ENODEV; -	max = le16_to_cpu(ep->desc.wMaxPacketSize); +	max = usb_endpoint_maxp(&ep->desc);  	if (max <= 0) {  		dev_dbg(&dev->dev,  			"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", @@ -366,7 +399,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  	if (xfertype == USB_ENDPOINT_XFER_ISOC) {  		int	n, len; -		/* FIXME SuperSpeed isoc endpoints have up to 16 bursts */ +		/* SuperSpeed isoc endpoints have up to 16 bursts of up to +		 * 3 packets each +		 */ +		if (dev->speed == USB_SPEED_SUPER) { +			int     burst = 1 + ep->ss_ep_comp.bMaxBurst; +			int     mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); +			max *= burst; +			max *= mult; +		} +  		/* "high bandwidth" mode, 1-3 packets/uframe? */  		if (dev->speed == USB_SPEED_HIGH) {  			int	mult = 1 + ((max >> 11) & 0x03); @@ -383,31 +425,31 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  			urb->iso_frame_desc[n].status = -EXDEV;  			urb->iso_frame_desc[n].actual_length = 0;  		} +	} else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint && +			dev->speed != USB_SPEED_WIRELESS) { +		struct scatterlist *sg; +		int i; + +		for_each_sg(urb->sg, sg, urb->num_sgs - 1, i) +			if (sg->length % max) +				return -EINVAL;  	}  	/* the I/O buffer must be mapped/unmapped, except when length=0 */  	if (urb->transfer_buffer_length > INT_MAX)  		return -EMSGSIZE; -#ifdef DEBUG -	/* stuff that drivers shouldn't do, but which shouldn't +	/* +	 * stuff that drivers shouldn't do, but which shouldn't  	 * cause problems in HCDs if they get it wrong.  	 */ -	{ -	unsigned int	orig_flags = urb->transfer_flags; -	unsigned int	allowed; -	static int pipetypes[4] = { -		PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT -	};  	/* Check that the pipe's type matches the endpoint's type */ -	if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) { -		dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", +	if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) +		dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",  			usb_pipetype(urb->pipe), pipetypes[xfertype]); -		return -EPIPE;		/* The most suitable error code :-) */ -	} -	/* enforce simple/standard policy */ +	/* Check against a simple/standard policy */  	allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK |  			URB_FREE_BUFFER);  	switch (xfertype) { @@ -426,16 +468,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  		allowed |= URB_ISO_ASAP;  		break;  	} -	urb->transfer_flags &= allowed; +	allowed &= urb->transfer_flags; + +	/* warn if submitter gave bogus flags */ +	if (allowed != urb->transfer_flags) +		dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n", +			urb->transfer_flags, allowed); -	/* fail if submitter gave bogus flags */ -	if (urb->transfer_flags != orig_flags) { -		dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n", -			orig_flags, urb->transfer_flags); -		return -EINVAL; -	} -	} -#endif  	/*  	 * Force periodic transfer intervals to be legal values that are  	 * a power of two (so HCDs don't need to). @@ -450,9 +489,9 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  		/* too small? */  		switch (dev->speed) {  		case USB_SPEED_WIRELESS: -			if (urb->interval < 6) +			if ((urb->interval < 6) +				&& (xfertype == USB_ENDPOINT_XFER_INT))  				return -EINVAL; -			break;  		default:  			if (urb->interval <= 0)  				return -EINVAL; @@ -523,15 +562,25 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);   * a driver's I/O routines to insure that all URB-related activity has   * completed before it returns.   * - * This request is always asynchronous.  Success is indicated by - * returning -EINPROGRESS, at which time the URB will probably not yet - * have been given back to the device driver.  When it is eventually - * called, the completion function will see @urb->status == -ECONNRESET. + * This request is asynchronous, however the HCD might call the ->complete() + * callback during unlink. Therefore when drivers call usb_unlink_urb(), they + * must not hold any locks that may be taken by the completion function. + * Success is indicated by returning -EINPROGRESS, at which time the URB will + * probably not yet have been given back to the device driver. When it is + * eventually called, the completion function will see @urb->status == + * -ECONNRESET.   * Failure is indicated by usb_unlink_urb() returning any other value.   * Unlinking will fail when @urb is not currently "linked" (i.e., it was   * never submitted, or it was unlinked before, or the hardware is already   * finished with it), even if the completion handler has not yet run.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * + * Return: -EINPROGRESS on success. See description for other values on + * failure. + *   * Unlinking and Endpoint Queues:   *   * [The behaviors and guarantees described below do not apply to virtual @@ -596,6 +645,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);   * with error -EPERM.  Thus even if the URB's completion handler always   * tries to resubmit, it will not succeed and the URB will become idle.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + *   * This routine may not be used in an interrupt context (such as a bottom   * half or a completion handler), or when holding a spinlock, or in other   * situations where the caller can't schedule(). @@ -633,6 +686,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);   * with error -EPERM.  Thus even if the URB's completion handler always   * tries to resubmit, it will not succeed and the URB will become idle.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + *   * This routine may not be used in an interrupt context (such as a bottom   * half or a completion handler), or when holding a spinlock, or in other   * situations where the caller can't schedule(). @@ -643,10 +700,13 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);  void usb_poison_urb(struct urb *urb)  {  	might_sleep(); -	if (!(urb && urb->dev && urb->ep)) +	if (!urb)  		return;  	atomic_inc(&urb->reject); +	if (!urb->dev || !urb->ep) +		return; +  	usb_hcd_unlink_urb(urb, -ENOENT);  	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);  } @@ -662,6 +722,27 @@ void usb_unpoison_urb(struct urb *urb)  EXPORT_SYMBOL_GPL(usb_unpoison_urb);  /** + * usb_block_urb - reliably prevent further use of an URB + * @urb: pointer to URB to be blocked, may be NULL + * + * After the routine has run, attempts to resubmit the URB will fail + * with error -EPERM.  Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + */ +void usb_block_urb(struct urb *urb) +{ +	if (!urb) +		return; + +	atomic_inc(&urb->reject); +} +EXPORT_SYMBOL_GPL(usb_block_urb); + +/**   * usb_kill_anchored_urbs - cancel transfer requests en masse   * @anchor: anchor the requests are bound to   * @@ -750,7 +831,7 @@ EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);   *   * this allows all outstanding URBs to be unlinked starting   * from the back of the queue. This function is asynchronous. - * The unlinking is just tiggered. It may happen after this + * The unlinking is just triggered. It may happen after this   * function has returned.   *   * This routine should not be called by a driver after its disconnect @@ -768,17 +849,53 @@ void usb_unlink_anchored_urbs(struct usb_anchor *anchor)  EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);  /** + * usb_anchor_suspend_wakeups + * @anchor: the anchor you want to suspend wakeups on + * + * Call this to stop the last urb being unanchored from waking up any + * usb_wait_anchor_empty_timeout waiters. This is used in the hcd urb give- + * back path to delay waking up until after the completion handler has run. + */ +void usb_anchor_suspend_wakeups(struct usb_anchor *anchor) +{ +	if (anchor) +		atomic_inc(&anchor->suspend_wakeups); +} +EXPORT_SYMBOL_GPL(usb_anchor_suspend_wakeups); + +/** + * usb_anchor_resume_wakeups + * @anchor: the anchor you want to resume wakeups on + * + * Allow usb_wait_anchor_empty_timeout waiters to be woken up again, and + * wake up any current waiters if the anchor is empty. + */ +void usb_anchor_resume_wakeups(struct usb_anchor *anchor) +{ +	if (!anchor) +		return; + +	atomic_dec(&anchor->suspend_wakeups); +	if (usb_anchor_check_wakeup(anchor)) +		wake_up(&anchor->wait); +} +EXPORT_SYMBOL_GPL(usb_anchor_resume_wakeups); + +/**   * usb_wait_anchor_empty_timeout - wait for an anchor to be unused   * @anchor: the anchor you want to become unused   * @timeout: how long you are willing to wait in milliseconds   *   * Call this is you want to be sure all an anchor's   * URBs have finished + * + * Return: Non-zero if the anchor became unused. Zero on timeout.   */  int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,  				  unsigned int timeout)  { -	return wait_event_timeout(anchor->wait, list_empty(&anchor->urb_list), +	return wait_event_timeout(anchor->wait, +				  usb_anchor_check_wakeup(anchor),  				  msecs_to_jiffies(timeout));  }  EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); @@ -787,8 +904,11 @@ EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);   * usb_get_from_anchor - get an anchor's oldest urb   * @anchor: the anchor whose urb you want   * - * this will take the oldest urb from an anchor, + * This will take the oldest urb from an anchor,   * unanchor and return it + * + * Return: The oldest urb from @anchor, or %NULL if @anchor has no + * urbs associated with it.   */  struct urb *usb_get_from_anchor(struct usb_anchor *anchor)  { @@ -837,7 +957,7 @@ EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs);   * usb_anchor_empty - is an anchor empty   * @anchor: the anchor you want to query   * - * returns 1 if the anchor has no urbs associated with it + * Return: 1 if the anchor has no urbs associated with it.   */  int usb_anchor_empty(struct usb_anchor *anchor)  { diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c new file mode 100644 index 00000000000..2776cfe64c0 --- /dev/null +++ b/drivers/usb/core/usb-acpi.c @@ -0,0 +1,228 @@ +/* + * USB-ACPI glue code + * + * Copyright 2012 Red Hat <mjg@redhat.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + */ +#include <linux/module.h> +#include <linux/usb.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/acpi.h> +#include <linux/pci.h> +#include <linux/usb/hcd.h> + +#include "hub.h" + +/** + * usb_acpi_power_manageable - check whether usb port has + * acpi power resource. + * @hdev: USB device belonging to the usb hub + * @index: port index based zero + * + * Return true if the port has acpi power resource and false if no. + */ +bool usb_acpi_power_manageable(struct usb_device *hdev, int index) +{ +	acpi_handle port_handle; +	int port1 = index + 1; + +	port_handle = usb_get_hub_port_acpi_handle(hdev, +		port1); +	if (port_handle) +		return acpi_bus_power_manageable(port_handle); +	else +		return false; +} +EXPORT_SYMBOL_GPL(usb_acpi_power_manageable); + +/** + * usb_acpi_set_power_state - control usb port's power via acpi power + * resource + * @hdev: USB device belonging to the usb hub + * @index: port index based zero + * @enable: power state expected to be set + * + * Notice to use usb_acpi_power_manageable() to check whether the usb port + * has acpi power resource before invoking this function. + * + * Returns 0 on success, else negative errno. + */ +int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable) +{ +	struct usb_hub *hub = usb_hub_to_struct_hub(hdev); +	struct usb_port *port_dev; +	acpi_handle port_handle; +	unsigned char state; +	int port1 = index + 1; +	int error = -EINVAL; + +	if (!hub) +		return -ENODEV; +	port_dev = hub->ports[port1 - 1]; + +	port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1); +	if (!port_handle) +		return error; + +	if (enable) +		state = ACPI_STATE_D0; +	else +		state = ACPI_STATE_D3_COLD; + +	error = acpi_bus_set_power(port_handle, state); +	if (!error) +		dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable); +	else +		dev_dbg(&port_dev->dev, "acpi: power failed to be set\n"); + +	return error; +} +EXPORT_SYMBOL_GPL(usb_acpi_set_power_state); + +static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle, +		struct acpi_pld_info *pld) +{ +	enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN; +	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; +	union acpi_object *upc; +	acpi_status status; + +	/* +	 * According to ACPI Spec 9.13. PLD indicates whether usb port is +	 * user visible and _UPC indicates whether it is connectable. If +	 * the port was visible and connectable, it could be freely connected +	 * and disconnected with USB devices. If no visible and connectable, +	 * a usb device is directly hard-wired to the port. If no visible and +	 * no connectable, the port would be not used. +	 */ +	status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer); +	upc = buffer.pointer; +	if (!upc || (upc->type != ACPI_TYPE_PACKAGE) +		|| upc->package.count != 4) { +		goto out; +	} + +	if (upc->package.elements[0].integer.value) +		if (pld->user_visible) +			connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG; +		else +			connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED; +	else if (!pld->user_visible) +		connect_type = USB_PORT_NOT_USED; +out: +	kfree(upc); +	return connect_type; +} + + +/* + * Private to usb-acpi, all the core needs to know is that + * port_dev->location is non-zero when it has been set by the firmware. + */ +#define USB_ACPI_LOCATION_VALID (1 << 31) + +static struct acpi_device *usb_acpi_find_companion(struct device *dev) +{ +	struct usb_device *udev; +	struct acpi_device *adev; +	acpi_handle *parent_handle; + +	/* +	 * In the ACPI DSDT table, only usb root hub and usb ports are +	 * acpi device nodes. The hierarchy like following. +	 * Device (EHC1) +	 *	Device (HUBN) +	 *		Device (PR01) +	 *			Device (PR11) +	 *			Device (PR12) +	 *			Device (PR13) +	 *			... +	 * So all binding process is divided into two parts. binding +	 * root hub and usb ports. +	 */ +	if (is_usb_device(dev)) { +		udev = to_usb_device(dev); +		if (udev->parent) +			return NULL; + +		/* root hub is only child (_ADR=0) under its parent, the HC */ +		adev = ACPI_COMPANION(dev->parent); +		return acpi_find_child_device(adev, 0, false); +	} else if (is_usb_port(dev)) { +		struct usb_port *port_dev = to_usb_port(dev); +		int port1 = port_dev->portnum; +		struct acpi_pld_info *pld; +		acpi_handle *handle; +		acpi_status status; + +		/* Get the struct usb_device point of port's hub */ +		udev = to_usb_device(dev->parent->parent); + +		/* +		 * The root hub ports' parent is the root hub. The non-root-hub +		 * ports' parent is the parent hub port which the hub is +		 * connected to. +		 */ +		if (!udev->parent) { +			struct usb_hcd *hcd = bus_to_hcd(udev->bus); +			int raw; + +			raw = usb_hcd_find_raw_port_number(hcd, port1); +			adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev), +					raw, false); +			if (!adev) +				return NULL; +		} else { +			parent_handle = +				usb_get_hub_port_acpi_handle(udev->parent, +				udev->portnum); +			if (!parent_handle) +				return NULL; + +			acpi_bus_get_device(parent_handle, &adev); +			adev = acpi_find_child_device(adev, port1, false); +			if (!adev) +				return NULL; +		} +		handle = adev->handle; +		status = acpi_get_physical_device_location(handle, &pld); +		if (ACPI_FAILURE(status) || !pld) +			return adev; + +		port_dev->location = USB_ACPI_LOCATION_VALID +			| pld->group_token << 8 | pld->group_position; +		port_dev->connect_type = usb_acpi_get_connect_type(handle, pld); +		ACPI_FREE(pld); + +		return adev; +	} + +	return NULL; +} + +static bool usb_acpi_bus_match(struct device *dev) +{ +	return is_usb_device(dev) || is_usb_port(dev); +} + +static struct acpi_bus_type usb_acpi_bus = { +	.name = "USB", +	.match = usb_acpi_bus_match, +	.find_companion = usb_acpi_find_companion, +}; + +int usb_acpi_register(void) +{ +	return register_acpi_bus_type(&usb_acpi_bus); +} + +void usb_acpi_unregister(void) +{ +	unregister_acpi_bus_type(&usb_acpi_bus); +} diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index fdd4130fbb7..4d1144990d4 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -47,9 +47,9 @@  const char *usbcore_name = "usbcore"; -static int nousb;	/* Disable USB when built into kernel image */ +static bool nousb;	/* Disable USB when built into kernel image */ -#ifdef	CONFIG_USB_SUSPEND +#ifdef	CONFIG_PM_RUNTIME  static int usb_autosuspend_delay = 2;		/* Default delay value,  						 * in seconds */  module_param_named(autosuspend, usb_autosuspend_delay, int, 0644); @@ -68,6 +68,8 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay");   * @alt_num: alternate interface setting number to search for.   *   * Search the configuration's interface cache for the given alt setting. + * + * Return: The alternate setting, if found. %NULL otherwise.   */  struct usb_host_interface *usb_find_alt_setting(  		struct usb_host_config *config, @@ -103,8 +105,7 @@ EXPORT_SYMBOL_GPL(usb_find_alt_setting);   * @ifnum: the desired interface   *   * This walks the device descriptor for the currently active configuration - * and returns a pointer to the interface with that particular interface - * number, or null. + * to find the interface object with the particular interface number.   *   * Note that configuration descriptors are not required to assign interface   * numbers sequentially, so that it would be incorrect to assume that @@ -115,6 +116,9 @@ EXPORT_SYMBOL_GPL(usb_find_alt_setting);   *   * Don't call this function unless you are bound to one of the interfaces   * on this device or you have locked the device! + * + * Return: A pointer to the interface that has @ifnum as interface number, + * if found. %NULL otherwise.   */  struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,  				      unsigned ifnum) @@ -139,8 +143,7 @@ EXPORT_SYMBOL_GPL(usb_ifnum_to_if);   * @altnum: the desired alternate setting number   *   * This searches the altsetting array of the specified interface for - * an entry with the correct bAlternateSetting value and returns a pointer - * to that entry, or null. + * an entry with the correct bAlternateSetting value.   *   * Note that altsettings need not be stored sequentially by number, so   * it would be incorrect to assume that the first altsetting entry in @@ -149,6 +152,9 @@ EXPORT_SYMBOL_GPL(usb_ifnum_to_if);   *   * Don't call this function unless you are bound to the intf interface   * or you have locked the device! + * + * Return: A pointer to the entry of the altsetting array of @intf that + * has @altnum as the alternate setting number. %NULL if not found.   */  struct usb_host_interface *usb_altnum_to_altsetting(  					const struct usb_interface *intf, @@ -191,6 +197,8 @@ static int __find_interface(struct device *dev, void *data)   * This walks the bus device list and returns a pointer to the interface   * with the matching minor and driver.  Note, this only works for devices   * that share the USB major number. + * + * Return: A pointer to the interface with the matching major and @minor.   */  struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)  { @@ -209,6 +217,39 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)  }  EXPORT_SYMBOL_GPL(usb_find_interface); +struct each_dev_arg { +	void *data; +	int (*fn)(struct usb_device *, void *); +}; + +static int __each_dev(struct device *dev, void *data) +{ +	struct each_dev_arg *arg = (struct each_dev_arg *)data; + +	/* There are struct usb_interface on the same bus, filter them out */ +	if (!is_usb_device(dev)) +		return 0; + +	return arg->fn(container_of(dev, struct usb_device, dev), arg->data); +} + +/** + * usb_for_each_dev - iterate over all USB devices in the system + * @data: data pointer that will be handed to the callback function + * @fn: callback function to be called for each USB device + * + * Iterate over all USB devices and call @fn for each, passing it @data. If it + * returns anything other than 0, we break the iteration prematurely and return + * that value. + */ +int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)) +{ +	struct each_dev_arg arg = {data, fn}; + +	return bus_for_each_dev(&usb_bus_type, NULL, &arg, __each_dev); +} +EXPORT_SYMBOL_GPL(usb_for_each_dev); +  /**   * usb_release_dev - free a usb device structure when all users of it are finished.   * @dev: device that's been disconnected @@ -225,6 +266,7 @@ static void usb_release_dev(struct device *dev)  	hcd = bus_to_hcd(udev->bus);  	usb_destroy_configuration(udev); +	usb_release_bos_descriptor(udev);  	usb_put_hcd(hcd);  	kfree(udev->product);  	kfree(udev->manufacturer); @@ -232,7 +274,6 @@ static void usb_release_dev(struct device *dev)  	kfree(udev);  } -#ifdef	CONFIG_HOTPLUG  static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)  {  	struct usb_device *usb_dev; @@ -248,14 +289,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)  	return 0;  } -#else - -static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) -{ -	return -ENODEV; -} -#endif	/* CONFIG_HOTPLUG */ -  #ifdef	CONFIG_PM  /* USB device Power-Management thunks. @@ -273,7 +306,7 @@ static int usb_dev_prepare(struct device *dev)  static void usb_dev_complete(struct device *dev)  {  	/* Currently used only for rebinding interfaces */ -	usb_resume(dev, PMSG_ON);	/* FIXME: change to PMSG_COMPLETE */ +	usb_resume_complete(dev);  }  static int usb_dev_suspend(struct device *dev) @@ -315,12 +348,18 @@ static const struct dev_pm_ops usb_device_pm_ops = {  	.thaw =		usb_dev_thaw,  	.poweroff =	usb_dev_poweroff,  	.restore =	usb_dev_restore, +#ifdef CONFIG_PM_RUNTIME +	.runtime_suspend =	usb_runtime_suspend, +	.runtime_resume =	usb_runtime_resume, +	.runtime_idle =		usb_runtime_idle, +#endif  };  #endif	/* CONFIG_PM */ -static char *usb_devnode(struct device *dev, mode_t *mode) +static char *usb_devnode(struct device *dev, +			 umode_t *mode, kuid_t *uid, kgid_t *gid)  {  	struct usb_device *usb_dev; @@ -359,19 +398,22 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus)   * controllers) should ever call this.   *   * This call may not be used in a non-sleeping context. + * + * Return: On success, a pointer to the allocated usb device. %NULL on + * failure.   */  struct usb_device *usb_alloc_dev(struct usb_device *parent,  				 struct usb_bus *bus, unsigned port1)  {  	struct usb_device *dev; -	struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); +	struct usb_hcd *usb_hcd = bus_to_hcd(bus);  	unsigned root_hub = 0;  	dev = kzalloc(sizeof(*dev), GFP_KERNEL);  	if (!dev)  		return NULL; -	if (!usb_get_hcd(bus_to_hcd(bus))) { +	if (!usb_get_hcd(usb_hcd)) {  		kfree(dev);  		return NULL;  	} @@ -390,6 +432,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,  	dev->dev.dma_mask = bus->controller->dma_mask;  	set_dev_node(&dev->dev, dev_to_node(bus->controller));  	dev->state = USB_STATE_ATTACHED; +	dev->lpm_disable_count = 1;  	atomic_set(&dev->urbnum, 0);  	INIT_LIST_HEAD(&dev->ep0.urb_list); @@ -445,7 +488,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,  	INIT_LIST_HEAD(&dev->filelist);  #ifdef	CONFIG_PM -	dev->autosuspend_delay = usb_autosuspend_delay * HZ; +	pm_runtime_set_autosuspend_delay(&dev->dev, +			usb_autosuspend_delay * 1000);  	dev->connect_time = jiffies;  	dev->active_duration = -jiffies;  #endif @@ -453,7 +497,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,  		dev->authorized = 1;  	else {  		dev->authorized = usb_hcd->authorized_default; -		dev->wusb = usb_bus_is_wusb(bus)? 1 : 0; +		dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;  	}  	return dev;  } @@ -468,7 +512,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,   * their probe() methods, when they bind to an interface, and release   * them by calling usb_put_dev(), in their disconnect() methods.   * - * A pointer to the device with the incremented reference counter is returned. + * Return: A pointer to the device with the incremented reference counter.   */  struct usb_device *usb_get_dev(struct usb_device *dev)  { @@ -502,8 +546,7 @@ EXPORT_SYMBOL_GPL(usb_put_dev);   * their probe() methods, when they bind to an interface, and release   * them by calling usb_put_intf(), in their disconnect() methods.   * - * A pointer to the interface with the incremented reference counter is - * returned. + * Return: A pointer to the interface with the incremented reference counter.   */  struct usb_interface *usb_get_intf(struct usb_interface *intf)  { @@ -556,7 +599,7 @@ EXPORT_SYMBOL_GPL(usb_put_intf);   * disconnect; in some drivers (such as usb-storage) the disconnect()   * or suspend() method will block waiting for a device reset to complete.   * - * Returns a negative error code for failure, otherwise 0. + * Return: A negative error code for failure, otherwise 0.   */  int usb_lock_device_for_reset(struct usb_device *udev,  			      const struct usb_interface *iface) @@ -595,14 +638,15 @@ EXPORT_SYMBOL_GPL(usb_lock_device_for_reset);   * usb_get_current_frame_number - return current bus frame number   * @dev: the device whose bus is being queried   * - * Returns the current frame number for the USB host controller - * used with the given USB device.  This can be used when scheduling + * Return: The current frame number for the USB host controller used + * with the given USB device. This can be used when scheduling   * isochronous requests.   * - * Note that different kinds of host controller have different - * "scheduling horizons".  While one type might support scheduling only - * 32 frames into the future, others could support scheduling up to - * 1024 frames into the future. + * Note: Different kinds of host controller have different "scheduling + * horizons". While one type might support scheduling only 32 frames + * into the future, others could support scheduling up to 1024 frames + * into the future. + *   */  int usb_get_current_frame_number(struct usb_device *dev)  { @@ -652,11 +696,12 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);   * @mem_flags: affect whether allocation may block   * @dma: used to return DMA address of buffer   * - * Return value is either null (indicating no buffer could be allocated), or - * the cpu-space pointer to a buffer that may be used to perform DMA to the + * Return: Either null (indicating no buffer could be allocated), or the + * cpu-space pointer to a buffer that may be used to perform DMA to the   * specified device.  Such cpu-space buffers are returned along with the DMA   * address (through the pointer provided).   * + * Note:   * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags   * to avoid behaviors like using "DMA bounce buffers", or thrashing IOMMU   * hardware during URB completion/resubmit.  The implementation varies between @@ -702,17 +747,18 @@ EXPORT_SYMBOL_GPL(usb_free_coherent);   * usb_buffer_map - create DMA mapping(s) for an urb   * @urb: urb whose transfer_buffer/setup_packet will be mapped   * - * Return value is either null (indicating no buffer could be mapped), or - * the parameter.  URB_NO_TRANSFER_DMA_MAP is - * added to urb->transfer_flags if the operation succeeds.  If the device - * is connected to this system through a non-DMA controller, this operation - * always succeeds. + * URB_NO_TRANSFER_DMA_MAP is added to urb->transfer_flags if the operation + * succeeds. If the device is connected to this system through a non-DMA + * controller, this operation always succeeds.   *   * This call would normally be used for an urb which is reused, perhaps   * as the target of a large periodic transfer, with usb_buffer_dmasync()   * calls to synchronize memory and dma state.   *   * Reverse the effect of this call with usb_buffer_unmap(). + * + * Return: Either %NULL (indicating no buffer could be mapped), or @urb. + *   */  #if 0  struct urb *usb_buffer_map(struct urb *urb) @@ -817,9 +863,10 @@ EXPORT_SYMBOL_GPL(usb_buffer_unmap);   * @sg: the scatterlist to map   * @nents: the number of entries in the scatterlist   * - * Return value is either < 0 (indicating no buffers could be mapped), or - * the number of DMA mapping array entries in the scatterlist. + * Return: Either < 0 (indicating no buffers could be mapped), or the + * number of DMA mapping array entries in the scatterlist.   * + * Note:   * The caller is responsible for placing the resulting DMA addresses from   * the scatterlist into URB transfer buffer pointers, and for setting the   * URB_NO_TRANSFER_DMA_MAP transfer flag in each of those URBs. @@ -947,8 +994,7 @@ static int usb_bus_notify(struct notifier_block *nb, unsigned long action,  		if (dev->type == &usb_device_type)  			(void) usb_create_sysfs_dev_files(to_usb_device(dev));  		else if (dev->type == &usb_if_device_type) -			(void) usb_create_sysfs_intf_files( -					to_usb_interface(dev)); +			usb_create_sysfs_intf_files(to_usb_interface(dev));  		break;  	case BUS_NOTIFY_DEL_DEVICE: @@ -1009,6 +1055,7 @@ static int __init usb_init(void)  	if (retval)  		goto out; +	usb_acpi_register();  	retval = bus_register(&usb_bus_type);  	if (retval)  		goto bus_register_failed; @@ -1024,9 +1071,6 @@ static int __init usb_init(void)  	retval = usb_devio_init();  	if (retval)  		goto usb_devio_init_failed; -	retval = usbfs_init(); -	if (retval) -		goto fs_init_failed;  	retval = usb_hub_init();  	if (retval)  		goto hub_init_failed; @@ -1036,8 +1080,6 @@ static int __init usb_init(void)  	usb_hub_cleanup();  hub_init_failed: -	usbfs_cleanup(); -fs_init_failed:  	usb_devio_cleanup();  usb_devio_init_failed:  	usb_deregister(&usbfs_driver); @@ -1048,6 +1090,7 @@ major_init_failed:  bus_notifier_failed:  	bus_unregister(&usb_bus_type);  bus_register_failed: +	usb_acpi_unregister();  	usb_debugfs_cleanup();  out:  	return retval; @@ -1064,12 +1107,12 @@ static void __exit usb_exit(void)  	usb_deregister_device_driver(&usb_generic_driver);  	usb_major_cleanup(); -	usbfs_cleanup();  	usb_deregister(&usbfs_driver);  	usb_devio_cleanup();  	usb_hub_cleanup();  	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);  	bus_unregister(&usb_bus_type); +	usb_acpi_unregister();  	usb_debugfs_cleanup();  } diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index cd882203ad3..d9d08720c38 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -1,10 +1,14 @@  #include <linux/pm.h> +#include <linux/acpi.h> + +struct usb_hub_descriptor; +struct usb_dev_state;  /* Functions local to drivers/usb/core/ */  extern int usb_create_sysfs_dev_files(struct usb_device *dev);  extern void usb_remove_sysfs_dev_files(struct usb_device *dev); -extern int usb_create_sysfs_intf_files(struct usb_interface *intf); +extern void usb_create_sysfs_intf_files(struct usb_interface *intf);  extern void usb_remove_sysfs_intf_files(struct usb_interface *intf);  extern int usb_create_ep_devs(struct device *parent,  				struct usb_host_endpoint *endpoint, @@ -24,25 +28,37 @@ extern void usb_disable_device(struct usb_device *dev, int skip_ep0);  extern int usb_deauthorize_device(struct usb_device *);  extern int usb_authorize_device(struct usb_device *);  extern void usb_detect_quirks(struct usb_device *udev); +extern void usb_detect_interface_quirks(struct usb_device *udev);  extern int usb_remove_device(struct usb_device *udev);  extern int usb_get_device_descriptor(struct usb_device *dev,  		unsigned int size); +extern int usb_get_bos_descriptor(struct usb_device *dev); +extern void usb_release_bos_descriptor(struct usb_device *dev);  extern char *usb_cache_string(struct usb_device *udev, int index);  extern int usb_set_configuration(struct usb_device *dev, int configuration);  extern int usb_choose_configuration(struct usb_device *udev); +static inline unsigned usb_get_max_power(struct usb_device *udev, +		struct usb_host_config *c) +{ +	/* SuperSpeed power is in 8 mA units; others are in 2 mA units */ +	unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2); + +	return c->desc.bMaxPower * mul; +} +  extern void usb_kick_khubd(struct usb_device *dev); +extern int usb_match_one_id_intf(struct usb_device *dev, +				 struct usb_host_interface *intf, +				 const struct usb_device_id *id);  extern int usb_match_device(struct usb_device *dev,  			    const struct usb_device_id *id);  extern void usb_forced_unbind_intf(struct usb_interface *intf); -extern void usb_rebind_intf(struct usb_interface *intf); +extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev); -extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port, -		void *owner); -extern int usb_hub_release_port(struct usb_device *hdev, unsigned port, -		void *owner); -extern void usb_hub_release_all_ports(struct usb_device *hdev, void *owner); +extern void usb_hub_release_all_ports(struct usb_device *hdev, +		struct usb_dev_state *owner);  extern bool usb_device_is_owned(struct usb_device *udev);  extern int  usb_hub_init(void); @@ -54,6 +70,7 @@ extern void usb_major_cleanup(void);  extern int usb_suspend(struct device *dev, pm_message_t msg);  extern int usb_resume(struct device *dev, pm_message_t msg); +extern int usb_resume_complete(struct device *dev);  extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg);  extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); @@ -72,33 +89,36 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg)  #endif -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME  extern void usb_autosuspend_device(struct usb_device *udev); -extern void usb_try_autosuspend_device(struct usb_device *udev);  extern int usb_autoresume_device(struct usb_device *udev);  extern int usb_remote_wakeup(struct usb_device *dev); +extern int usb_runtime_suspend(struct device *dev); +extern int usb_runtime_resume(struct device *dev); +extern int usb_runtime_idle(struct device *dev); +extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable);  #else  #define usb_autosuspend_device(udev)		do {} while (0) -#define usb_try_autosuspend_device(udev)	do {} while (0)  static inline int usb_autoresume_device(struct usb_device *udev)  {  	return 0;  } -static inline int usb_remote_wakeup(struct usb_device *udev) +static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)  {  	return 0;  } -  #endif  extern struct bus_type usb_bus_type; +extern struct mutex usb_port_peer_mutex;  extern struct device_type usb_device_type;  extern struct device_type usb_if_device_type;  extern struct device_type usb_ep_device_type; +extern struct device_type usb_port_device_type;  extern struct usb_device_driver usb_generic_driver;  static inline int is_usb_device(const struct device *dev) @@ -116,6 +136,11 @@ static inline int is_usb_endpoint(const struct device *dev)  	return dev->type == &usb_ep_device_type;  } +static inline int is_usb_port(const struct device *dev) +{ +	return dev->type == &usb_port_device_type; +} +  /* Do the same for device drivers and interface drivers. */  static inline int is_usb_device_driver(struct device_driver *drv) @@ -124,7 +149,6 @@ static inline int is_usb_device_driver(struct device_driver *drv)  			for_devices;  } -  /* for labeling diagnostics */  extern const char *usbcore_name; @@ -142,9 +166,26 @@ extern void usbfs_conn_disc_event(void);  extern int usb_devio_init(void);  extern void usb_devio_cleanup(void); +/* + * Firmware specific cookie identifying a port's location. '0' == no location + * data available + */ +typedef u32 usb_port_location_t; +  /* internal notify stuff */  extern void usb_notify_add_device(struct usb_device *udev);  extern void usb_notify_remove_device(struct usb_device *udev);  extern void usb_notify_add_bus(struct usb_bus *ubus);  extern void usb_notify_remove_bus(struct usb_bus *ubus); - +extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev, +		struct usb_hub_descriptor *desc); + +#ifdef CONFIG_ACPI +extern int usb_acpi_register(void); +extern void usb_acpi_unregister(void); +extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, +	int port1); +#else +static inline int usb_acpi_register(void) { return 0; }; +static inline void usb_acpi_unregister(void) { }; +#endif  | 
