diff options
Diffstat (limited to 'drivers/usb/core/devio.c')
| -rw-r--r-- | drivers/usb/core/devio.c | 19 | 
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6833c918abce..d93d94d7ff50 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,11 +251,19 @@ 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) { -		dec_usb_memory_use_count(usbm, &usbm->vma_use_count); -		return -EAGAIN; +	if (hcd->localmem_pool || !hcd_uses_dma(hcd)) { +		if (remap_pfn_range(vma, vma->vm_start, +				    virt_to_phys(usbm->mem) >> PAGE_SHIFT, +				    size, vma->vm_page_prot) < 0) { +			dec_usb_memory_use_count(usbm, &usbm->vma_use_count); +			return -EAGAIN; +		} +	} else { +		if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, +				      size)) { +			dec_usb_memory_use_count(usbm, &usbm->vma_use_count); +			return -EAGAIN; +		}  	}  	vma->vm_flags |= VM_IO;  | 
