diff options
Diffstat (limited to 'drivers/usb/core/message.c')
| -rw-r--r-- | drivers/usb/core/message.c | 13 | 
1 files changed, 10 insertions, 3 deletions
| diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d5f834f16993..6197938dcc2d 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -589,12 +589,13 @@ void usb_sg_cancel(struct usb_sg_request *io)  	int i, retval;  	spin_lock_irqsave(&io->lock, flags); -	if (io->status) { +	if (io->status || io->count == 0) {  		spin_unlock_irqrestore(&io->lock, flags);  		return;  	}  	/* shut everything down */  	io->status = -ECONNRESET; +	io->count++;		/* Keep the request alive until we're done */  	spin_unlock_irqrestore(&io->lock, flags);  	for (i = io->entries - 1; i >= 0; --i) { @@ -608,6 +609,12 @@ void usb_sg_cancel(struct usb_sg_request *io)  			dev_warn(&io->dev->dev, "%s, unlink --> %d\n",  				 __func__, retval);  	} + +	spin_lock_irqsave(&io->lock, flags); +	io->count--; +	if (!io->count) +		complete(&io->complete); +	spin_unlock_irqrestore(&io->lock, flags);  }  EXPORT_SYMBOL_GPL(usb_sg_cancel); @@ -1137,11 +1144,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,  	if (usb_endpoint_out(epaddr)) {  		ep = dev->ep_out[epnum]; -		if (reset_hardware) +		if (reset_hardware && epnum != 0)  			dev->ep_out[epnum] = NULL;  	} else {  		ep = dev->ep_in[epnum]; -		if (reset_hardware) +		if (reset_hardware && epnum != 0)  			dev->ep_in[epnum] = NULL;  	}  	if (ep) { |