diff options
Diffstat (limited to 'drivers/usb/core/message.c')
| -rw-r--r-- | drivers/usb/core/message.c | 40 | 
1 files changed, 24 insertions, 16 deletions
| diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index de51667dd64..31fb204f44c 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1039,14 +1039,15 @@ static void remove_intf_ep_devs(struct usb_interface *intf)   * @dev: the device whose endpoint is being disabled   * @epaddr: the endpoint's address.  Endpoint number for output,   *	endpoint number + USB_DIR_IN for input + * @reset_hardware: flag to erase any endpoint state stored in the + *	controller hardware   * - * Deallocates hcd/hardware state for this endpoint ... and nukes all - * pending urbs. - * - * If the HCD hasn't registered a disable() function, this sets the - * endpoint's maxpacket size to 0 to prevent further submissions. + * Disables the endpoint for URB submission and nukes all pending URBs. + * If @reset_hardware is set then also deallocates hcd/hardware state + * for the endpoint.   */ -void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) +void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, +		bool reset_hardware)  {  	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;  	struct usb_host_endpoint *ep; @@ -1056,15 +1057,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)  	if (usb_endpoint_out(epaddr)) {  		ep = dev->ep_out[epnum]; -		dev->ep_out[epnum] = NULL; +		if (reset_hardware) +			dev->ep_out[epnum] = NULL;  	} else {  		ep = dev->ep_in[epnum]; -		dev->ep_in[epnum] = NULL; +		if (reset_hardware) +			dev->ep_in[epnum] = NULL;  	}  	if (ep) {  		ep->enabled = 0;  		usb_hcd_flush_endpoint(dev, ep); -		usb_hcd_disable_endpoint(dev, ep); +		if (reset_hardware) +			usb_hcd_disable_endpoint(dev, ep);  	}  } @@ -1072,17 +1076,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)   * usb_disable_interface -- Disable all endpoints for an interface   * @dev: the device whose interface is being disabled   * @intf: pointer to the interface descriptor + * @reset_hardware: flag to erase any endpoint state stored in the + *	controller hardware   *   * Disables all the endpoints for the interface's current altsetting.   */ -void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) +void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, +		bool reset_hardware)  {  	struct usb_host_interface *alt = intf->cur_altsetting;  	int i;  	for (i = 0; i < alt->desc.bNumEndpoints; ++i) {  		usb_disable_endpoint(dev, -				alt->endpoint[i].desc.bEndpointAddress); +				alt->endpoint[i].desc.bEndpointAddress, +				reset_hardware);  	}  } @@ -1103,8 +1111,8 @@ 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");  	for (i = skip_ep0; i < 16; ++i) { -		usb_disable_endpoint(dev, i); -		usb_disable_endpoint(dev, i + USB_DIR_IN); +		usb_disable_endpoint(dev, i, true); +		usb_disable_endpoint(dev, i + USB_DIR_IN, true);  	}  	dev->toggle[0] = dev->toggle[1] = 0; @@ -1274,7 +1282,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  		remove_intf_ep_devs(iface);  		usb_remove_sysfs_intf_files(iface);  	} -	usb_disable_interface(dev, iface); +	usb_disable_interface(dev, iface, true);  	iface->cur_altsetting = alt; @@ -1353,8 +1361,8 @@ int usb_reset_configuration(struct usb_device *dev)  	 */  	for (i = 1; i < 16; ++i) { -		usb_disable_endpoint(dev, i); -		usb_disable_endpoint(dev, i + USB_DIR_IN); +		usb_disable_endpoint(dev, i, true); +		usb_disable_endpoint(dev, i + USB_DIR_IN, true);  	}  	config = dev->actconfig; | 
