diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/devio.c | 5 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 18 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 13 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 4 | 
4 files changed, 31 insertions, 9 deletions
| diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6833c918abce..b9db9812d6c5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)  {  	struct usb_memory *usbm = NULL;  	struct usb_dev_state *ps = file->private_data; +	struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus);  	size_t size = vma->vm_end - vma->vm_start;  	void *mem;  	unsigned long flags; @@ -250,9 +251,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)  	usbm->vma_use_count = 1;  	INIT_LIST_HEAD(&usbm->memlist); -	if (remap_pfn_range(vma, vma->vm_start, -			virt_to_phys(usbm->mem) >> PAGE_SHIFT, -			size, vma->vm_page_prot) < 0) { +	if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) {  		dec_usb_memory_use_count(usbm, &usbm->vma_use_count);  		return -EAGAIN;  	} diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 54cd8ef795ec..2b6565c06c23 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1223,6 +1223,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  #ifdef CONFIG_PM  			udev->reset_resume = 1;  #endif +			/* 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 hub_wq */ @@ -2723,13 +2728,11 @@ static bool use_new_scheme(struct usb_device *udev, int retry,  {  	int old_scheme_first_port =  		port_dev->quirks & USB_PORT_QUIRK_OLD_SCHEME; -	int quick_enumeration = (udev->speed == USB_SPEED_HIGH);  	if (udev->speed >= USB_SPEED_SUPER)  		return false; -	return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first -			      || quick_enumeration); +	return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first);  }  /* Is a USB 3.0 port in the Inactive or Compliance Mode state? @@ -3088,6 +3091,15 @@ static int check_port_resume_type(struct usb_device *udev,  		if (portchange & USB_PORT_STAT_C_ENABLE)  			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_ENABLE); + +		/* +		 * Whatever made this reset-resume necessary may have +		 * turned on the port1 bit in hub->change_bits.  But after +		 * a successful reset-resume we want the bit to be clear; +		 * if it was on it would indicate that something happened +		 * following the reset-resume. +		 */ +		clear_bit(port1, hub->change_bits);  	}  	return status; 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) { diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index da30b5664ff3..3e8efe759c3e 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -430,6 +430,10 @@ static const struct usb_device_id usb_quirk_list[] = {  	/* Corsair K70 LUX */  	{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, +	/* Corsair K70 RGB RAPDIFIRE */ +	{ USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT | +	  USB_QUIRK_DELAY_CTRL_MSG }, +  	/* MIDI keyboard WORLDE MINI */  	{ USB_DEVICE(0x1c75, 0x0204), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, |