diff options
Diffstat (limited to 'drivers/usb/core/message.c')
| -rw-r--r-- | drivers/usb/core/message.c | 66 | 
1 files changed, 33 insertions, 33 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 1ed5afd91e6..131f73649b6 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1540,7 +1540,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; @@ -1575,14 +1574,6 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)  	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, @@ -1795,7 +1786,8 @@ free_interfaces:  	if (dev->actconfig && usb_disable_lpm(dev)) {  		dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);  		mutex_unlock(hcd->bandwidth_mutex); -		return -ENOMEM; +		ret = -ENOMEM; +		goto free_interfaces;  	}  	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  	if (ret < 0) { @@ -1806,29 +1798,8 @@ free_interfaces:  		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); -	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); -		/* Leave LPM disabled while the device is unconfigured. */ -		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) { @@ -1872,6 +1843,35 @@ free_interfaces:  	}  	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);  | 
