diff options
Diffstat (limited to 'drivers/usb/core/buffer.c')
| -rw-r--r-- | drivers/usb/core/buffer.c | 41 | 
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index fbb087b728dc..268ccbec88f9 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -172,3 +172,44 @@ void hcd_buffer_free(  	}  	dma_free_coherent(hcd->self.sysdev, size, addr, dma);  } + +void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, +		size_t size, gfp_t mem_flags, dma_addr_t *dma) +{ +	if (size == 0) +		return NULL; + +	if (hcd->localmem_pool) +		return gen_pool_dma_alloc_align(hcd->localmem_pool, +				size, dma, PAGE_SIZE); + +	/* some USB hosts just use PIO */ +	if (!hcd_uses_dma(hcd)) { +		*dma = DMA_MAPPING_ERROR; +		return (void *)__get_free_pages(mem_flags, +				get_order(size)); +	} + +	return dma_alloc_coherent(hcd->self.sysdev, +			size, dma, mem_flags); +} + +void hcd_buffer_free_pages(struct usb_hcd *hcd, +		size_t size, void *addr, dma_addr_t dma) +{ +	if (!addr) +		return; + +	if (hcd->localmem_pool) { +		gen_pool_free(hcd->localmem_pool, +				(unsigned long)addr, size); +		return; +	} + +	if (!hcd_uses_dma(hcd)) { +		free_pages((unsigned long)addr, get_order(size)); +		return; +	} + +	dma_free_coherent(hcd->self.sysdev, size, addr, dma); +}  | 
