static void *snd_malloc_dev_pages_fallback(struct device *dev, size_t size, dma_addr_t *dma, size_t *res_size) { void *res; snd_assert(res_size != NULL, return NULL); do { if ((res = snd_malloc_dev_pages(dev, size, dma)) != NULL) { *res_size = size; return res; } size >>= 1; } while (size >= PAGE_SIZE); return NULL; }
/** * snd_dma_alloc_pages - allocate the buffer area according to the given type * @type: the DMA buffer type * @device: the device pointer * @size: the buffer size to allocate * @dmab: buffer allocation record to store the allocated data * * Calls the memory-allocator function for the corresponding * buffer type. * * Return: Zero if the buffer with the given size is allocated successfully, * otherwise a negative value on error. */ int snd_dma_alloc_pages(int type, struct device *device, size_t size, struct snd_dma_buffer *dmab) { if (WARN_ON(!size)) return -ENXIO; if (WARN_ON(!dmab)) return -ENXIO; dmab->dev.type = type; dmab->dev.dev = device; dmab->bytes = 0; switch (type) { case SNDRV_DMA_TYPE_CONTINUOUS: dmab->area = snd_malloc_pages(size, (__force gfp_t)(unsigned long)device); dmab->addr = 0; break; #ifdef CONFIG_HAS_DMA #ifdef CONFIG_GENERIC_ALLOCATOR case SNDRV_DMA_TYPE_DEV_IRAM: snd_malloc_dev_iram(dmab, size); if (dmab->area) break; /* Internal memory might have limited size and no enough space, * so if we fail to malloc, try to fetch memory traditionally. */ dmab->dev.type = SNDRV_DMA_TYPE_DEV; #endif /* CONFIG_GENERIC_ALLOCATOR */ case SNDRV_DMA_TYPE_DEV: dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); break; #endif #ifdef CONFIG_SND_DMA_SGBUF case SNDRV_DMA_TYPE_DEV_SG: snd_malloc_sgbuf_pages(device, size, dmab, NULL); break; #endif default: pr_err("snd-malloc: invalid device type %d\n", type); dmab->area = NULL; dmab->addr = 0; return -ENXIO; } if (! dmab->area) return -ENOMEM; dmab->bytes = size; return 0; }