.. | .. |
---|
170 | 170 | } |
---|
171 | 171 | dma_free_coherent(hcd->self.sysdev, size, addr, dma); |
---|
172 | 172 | } |
---|
| 173 | + |
---|
| 174 | +void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, |
---|
| 175 | + size_t size, gfp_t mem_flags, dma_addr_t *dma) |
---|
| 176 | +{ |
---|
| 177 | + if (size == 0) |
---|
| 178 | + return NULL; |
---|
| 179 | + |
---|
| 180 | + if (hcd->localmem_pool) |
---|
| 181 | + return gen_pool_dma_alloc_align(hcd->localmem_pool, |
---|
| 182 | + size, dma, PAGE_SIZE); |
---|
| 183 | + |
---|
| 184 | + /* some USB hosts just use PIO */ |
---|
| 185 | + if (!hcd_uses_dma(hcd)) { |
---|
| 186 | + *dma = DMA_MAPPING_ERROR; |
---|
| 187 | + return (void *)__get_free_pages(mem_flags, |
---|
| 188 | + get_order(size)); |
---|
| 189 | + } |
---|
| 190 | + |
---|
| 191 | + return dma_alloc_coherent(hcd->self.sysdev, |
---|
| 192 | + size, dma, mem_flags); |
---|
| 193 | +} |
---|
| 194 | + |
---|
| 195 | +void hcd_buffer_free_pages(struct usb_hcd *hcd, |
---|
| 196 | + size_t size, void *addr, dma_addr_t dma) |
---|
| 197 | +{ |
---|
| 198 | + if (!addr) |
---|
| 199 | + return; |
---|
| 200 | + |
---|
| 201 | + if (hcd->localmem_pool) { |
---|
| 202 | + gen_pool_free(hcd->localmem_pool, |
---|
| 203 | + (unsigned long)addr, size); |
---|
| 204 | + return; |
---|
| 205 | + } |
---|
| 206 | + |
---|
| 207 | + if (!hcd_uses_dma(hcd)) { |
---|
| 208 | + free_pages((unsigned long)addr, get_order(size)); |
---|
| 209 | + return; |
---|
| 210 | + } |
---|
| 211 | + |
---|
| 212 | + dma_free_coherent(hcd->self.sysdev, size, addr, dma); |
---|
| 213 | +} |
---|