sound: pcm: add vmalloc buffer helper functions
There are now five copies of the code to allocate a PCM buffer using vmalloc(). Add a sixth in the core so that the others can be removed. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
14d44e2c2c
commit
681b84e177
@@ -905,6 +905,44 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
|
|||||||
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
|
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
|
||||||
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
|
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
|
||||||
|
|
||||||
|
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
|
||||||
|
size_t size, gfp_t gfp_flags);
|
||||||
|
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
|
||||||
|
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
|
||||||
|
unsigned long offset);
|
||||||
|
#if 0 /* for kernel-doc */
|
||||||
|
/**
|
||||||
|
* snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer
|
||||||
|
* @substream: the substream to allocate the buffer to
|
||||||
|
* @size: the requested buffer size, in bytes
|
||||||
|
*
|
||||||
|
* Allocates the PCM substream buffer using vmalloc(), i.e., the memory is
|
||||||
|
* contiguous in kernel virtual space, but not in physical memory. Use this
|
||||||
|
* if the buffer is accessed by kernel code but not by device DMA.
|
||||||
|
*
|
||||||
|
* Returns 1 if the buffer was changed, 0 if not changed, or a negative error
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
static int snd_pcm_lib_alloc_vmalloc_buffer
|
||||||
|
(struct snd_pcm_substream *substream, size_t size);
|
||||||
|
/**
|
||||||
|
* snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer
|
||||||
|
* @substream: the substream to allocate the buffer to
|
||||||
|
* @size: the requested buffer size, in bytes
|
||||||
|
*
|
||||||
|
* This function works like snd_pcm_lib_alloc_vmalloc_buffer(), but uses
|
||||||
|
* vmalloc_32(), i.e., the pages are allocated from 32-bit-addressable memory.
|
||||||
|
*/
|
||||||
|
static int snd_pcm_lib_alloc_vmalloc_32_buffer
|
||||||
|
(struct snd_pcm_substream *substream, size_t size);
|
||||||
|
#endif
|
||||||
|
#define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \
|
||||||
|
_snd_pcm_lib_alloc_vmalloc_buffer \
|
||||||
|
(subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO)
|
||||||
|
#define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \
|
||||||
|
_snd_pcm_lib_alloc_vmalloc_buffer \
|
||||||
|
(subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
|
||||||
|
|
||||||
#ifdef CONFIG_SND_DMA_SGBUF
|
#ifdef CONFIG_SND_DMA_SGBUF
|
||||||
/*
|
/*
|
||||||
* SG-buffer handling
|
* SG-buffer handling
|
||||||
|
@@ -434,3 +434,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(snd_pcm_lib_free_pages);
|
EXPORT_SYMBOL(snd_pcm_lib_free_pages);
|
||||||
|
|
||||||
|
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
|
||||||
|
size_t size, gfp_t gfp_flags)
|
||||||
|
{
|
||||||
|
struct snd_pcm_runtime *runtime;
|
||||||
|
|
||||||
|
if (PCM_RUNTIME_CHECK(substream))
|
||||||
|
return -EINVAL;
|
||||||
|
runtime = substream->runtime;
|
||||||
|
if (runtime->dma_area) {
|
||||||
|
if (runtime->dma_bytes >= size)
|
||||||
|
return 0; /* already large enough */
|
||||||
|
vfree(runtime->dma_area);
|
||||||
|
}
|
||||||
|
runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
|
||||||
|
if (!runtime->dma_area)
|
||||||
|
return -ENOMEM;
|
||||||
|
runtime->dma_bytes = size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
|
||||||
|
* @substream: the substream with a buffer allocated by
|
||||||
|
* snd_pcm_lib_alloc_vmalloc_buffer()
|
||||||
|
*/
|
||||||
|
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
|
||||||
|
{
|
||||||
|
struct snd_pcm_runtime *runtime;
|
||||||
|
|
||||||
|
if (PCM_RUNTIME_CHECK(substream))
|
||||||
|
return -EINVAL;
|
||||||
|
runtime = substream->runtime;
|
||||||
|
vfree(runtime->dma_area);
|
||||||
|
runtime->dma_area = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
|
||||||
|
* @substream: the substream with a buffer allocated by
|
||||||
|
* snd_pcm_lib_alloc_vmalloc_buffer()
|
||||||
|
* @offset: offset in the buffer
|
||||||
|
*
|
||||||
|
* This function is to be used as the page callback in the PCM ops.
|
||||||
|
*/
|
||||||
|
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
|
||||||
|
unsigned long offset)
|
||||||
|
{
|
||||||
|
return vmalloc_to_page(substream->runtime->dma_area + offset);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);
|
||||||
|
Reference in New Issue
Block a user