aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm_memory.c')
-rw-r--r--sound/core/pcm_memory.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index b70ce3b69ab4..7bde7fb64011 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -163,19 +163,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
size_t size;
struct snd_dma_buffer new_dmab;
+ mutex_lock(&substream->pcm->open_mutex);
if (substream->runtime) {
buffer->error = -EBUSY;
- return;
+ goto unlock;
}
if (!snd_info_get_line(buffer, line, sizeof(line))) {
snd_info_get_str(str, line, sizeof(str));
size = simple_strtoul(str, NULL, 10) * 1024;
if ((size != 0 && size < 8192) || size > substream->dma_max) {
buffer->error = -EINVAL;
- return;
+ goto unlock;
}
if (substream->dma_buffer.bytes == size)
- return;
+ goto unlock;
memset(&new_dmab, 0, sizeof(new_dmab));
new_dmab.dev = substream->dma_buffer.dev;
if (size > 0) {
@@ -189,7 +190,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
substream->pcm->card->number, substream->pcm->device,
substream->stream ? 'c' : 'p', substream->number,
substream->pcm->name, size);
- return;
+ goto unlock;
}
substream->buffer_bytes_max = size;
} else {
@@ -201,6 +202,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
} else {
buffer->error = -EINVAL;
}
+ unlock:
+ mutex_unlock(&substream->pcm->open_mutex);
}
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
@@ -347,6 +350,8 @@ EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
* SNDRV_DMA_TYPE_VMALLOC type.
*
* Upon successful buffer allocation and setup, the function returns 0.
+ *
+ * Return: zero if successful, or a negative error code
*/
int snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
struct device *data, size_t size, size_t max)
@@ -366,6 +371,8 @@ EXPORT_SYMBOL(snd_pcm_set_managed_buffer);
*
* Do pre-allocation to all substreams of the given pcm for the specified DMA
* type and size, and set the managed_buffer_alloc flag to each substream.
+ *
+ * Return: zero if successful, or a negative error code
*/
int snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data,
@@ -450,7 +457,6 @@ EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
*/
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
{
- struct snd_card *card = substream->pcm->card;
struct snd_pcm_runtime *runtime;
if (PCM_RUNTIME_CHECK(substream))
@@ -459,6 +465,8 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
if (runtime->dma_area == NULL)
return 0;
if (runtime->dma_buffer_p != &substream->dma_buffer) {
+ struct snd_card *card = substream->pcm->card;
+
/* it's a newly allocated buffer. release it now. */
do_free_pages(card, runtime->dma_buffer_p);
kfree(runtime->dma_buffer_p);