summaryrefslogtreecommitdiff
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/memalloc.c113
-rw-r--r--sound/core/memalloc_local.h4
-rw-r--r--sound/core/oss/pcm_oss.c42
-rw-r--r--sound/core/pcm.c9
-rw-r--r--sound/core/pcm_compat.c4
-rw-r--r--sound/core/pcm_dmaengine.c8
-rw-r--r--sound/core/pcm_lib.c16
-rw-r--r--sound/core/pcm_native.c128
8 files changed, 154 insertions, 170 deletions
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index cfcd8eff4139..03cffe771366 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -18,25 +18,18 @@
#include <sound/memalloc.h>
#include "memalloc_local.h"
+#define DEFAULT_GFP \
+ (GFP_KERNEL | \
+ __GFP_COMP | /* compound page lets parts be mapped */ \
+ __GFP_RETRY_MAYFAIL | /* don't trigger OOM-killer */ \
+ __GFP_NOWARN) /* no stack trace print - this call is non-critical */
+
static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab);
#ifdef CONFIG_SND_DMA_SGBUF
-static void *do_alloc_fallback_pages(struct device *dev, size_t size,
- dma_addr_t *addr, bool wc);
-static void do_free_fallback_pages(void *p, size_t size, bool wc);
static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size);
#endif
-/* a cast to gfp flag from the dev pointer; for CONTINUOUS and VMALLOC types */
-static inline gfp_t snd_mem_get_gfp_flags(const struct snd_dma_buffer *dmab,
- gfp_t default_gfp)
-{
- if (!dmab->dev.dev)
- return default_gfp;
- else
- return (__force gfp_t)(unsigned long)dmab->dev.dev;
-}
-
static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
{
const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
@@ -284,24 +277,54 @@ EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
/*
* Continuous pages allocator
*/
-static void *do_alloc_pages(size_t size, dma_addr_t *addr, gfp_t gfp)
+static void *do_alloc_pages(struct device *dev, size_t size, dma_addr_t *addr,
+ bool wc)
{
- void *p = alloc_pages_exact(size, gfp);
+ void *p;
+ gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
- if (p)
- *addr = page_to_phys(virt_to_page(p));
+ again:
+ p = alloc_pages_exact(size, gfp);
+ if (!p)
+ return NULL;
+ *addr = page_to_phys(virt_to_page(p));
+ if (!dev)
+ return p;
+ if ((*addr + size - 1) & ~dev->coherent_dma_mask) {
+ if (IS_ENABLED(CONFIG_ZONE_DMA32) && !(gfp & GFP_DMA32)) {
+ gfp |= GFP_DMA32;
+ goto again;
+ }
+ if (IS_ENABLED(CONFIG_ZONE_DMA) && !(gfp & GFP_DMA)) {
+ gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+ goto again;
+ }
+ }
+#ifdef CONFIG_X86
+ if (wc)
+ set_memory_wc((unsigned long)(p), size >> PAGE_SHIFT);
+#endif
return p;
}
+static void do_free_pages(void *p, size_t size, bool wc)
+{
+#ifdef CONFIG_X86
+ if (wc)
+ set_memory_wb((unsigned long)(p), size >> PAGE_SHIFT);
+#endif
+ free_pages_exact(p, size);
+}
+
+
static void *snd_dma_continuous_alloc(struct snd_dma_buffer *dmab, size_t size)
{
- return do_alloc_pages(size, &dmab->addr,
- snd_mem_get_gfp_flags(dmab, GFP_KERNEL));
+ return do_alloc_pages(dmab->dev.dev, size, &dmab->addr, false);
}
static void snd_dma_continuous_free(struct snd_dma_buffer *dmab)
{
- free_pages_exact(dmab->area, dmab->bytes);
+ do_free_pages(dmab->area, dmab->bytes, false);
}
static int snd_dma_continuous_mmap(struct snd_dma_buffer *dmab,
@@ -324,9 +347,7 @@ static const struct snd_malloc_ops snd_dma_continuous_ops = {
*/
static void *snd_dma_vmalloc_alloc(struct snd_dma_buffer *dmab, size_t size)
{
- gfp_t gfp = snd_mem_get_gfp_flags(dmab, GFP_KERNEL | __GFP_HIGHMEM);
-
- return __vmalloc(size, gfp);
+ return vmalloc(size);
}
static void snd_dma_vmalloc_free(struct snd_dma_buffer *dmab)
@@ -440,12 +461,6 @@ static const struct snd_malloc_ops snd_dma_iram_ops = {
};
#endif /* CONFIG_GENERIC_ALLOCATOR */
-#define DEFAULT_GFP \
- (GFP_KERNEL | \
- __GFP_COMP | /* compound page lets parts be mapped */ \
- __GFP_NORETRY | /* don't trigger OOM-killer */ \
- __GFP_NOWARN) /* no stack trace print - this call is non-critical */
-
/*
* Coherent device pages allocator
*/
@@ -479,12 +494,12 @@ static const struct snd_malloc_ops snd_dma_dev_ops = {
#ifdef CONFIG_SND_DMA_SGBUF
static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
{
- return do_alloc_fallback_pages(dmab->dev.dev, size, &dmab->addr, true);
+ return do_alloc_pages(dmab->dev.dev, size, &dmab->addr, true);
}
static void snd_dma_wc_free(struct snd_dma_buffer *dmab)
{
- do_free_fallback_pages(dmab->area, dmab->bytes, true);
+ do_free_pages(dmab->area, dmab->bytes, true);
}
static int snd_dma_wc_mmap(struct snd_dma_buffer *dmab,
@@ -700,37 +715,6 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
.get_chunk_size = snd_dma_noncontig_get_chunk_size,
};
-/* manual page allocations with wc setup */
-static void *do_alloc_fallback_pages(struct device *dev, size_t size,
- dma_addr_t *addr, bool wc)
-{
- gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
- void *p;
-
- again:
- p = do_alloc_pages(size, addr, gfp);
- if (!p || (*addr + size - 1) & ~dev->coherent_dma_mask) {
- if (IS_ENABLED(CONFIG_ZONE_DMA32) && !(gfp & GFP_DMA32)) {
- gfp |= GFP_DMA32;
- goto again;
- }
- if (IS_ENABLED(CONFIG_ZONE_DMA) && !(gfp & GFP_DMA)) {
- gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
- goto again;
- }
- }
- if (p && wc)
- set_memory_wc((unsigned long)(p), size >> PAGE_SHIFT);
- return p;
-}
-
-static void do_free_fallback_pages(void *p, size_t size, bool wc)
-{
- if (wc)
- set_memory_wb((unsigned long)(p), size >> PAGE_SHIFT);
- free_pages_exact(p, size);
-}
-
/* Fallback SG-buffer allocations for x86 */
struct snd_dma_sg_fallback {
size_t count;
@@ -745,7 +729,7 @@ static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab,
size_t i;
for (i = 0; i < sgbuf->count && sgbuf->pages[i]; i++)
- do_free_fallback_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc);
+ do_free_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc);
kvfree(sgbuf->pages);
kvfree(sgbuf->addrs);
kfree(sgbuf);
@@ -772,8 +756,7 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
goto error;
for (i = 0; i < count; sgbuf->count++, i++) {
- p = do_alloc_fallback_pages(dmab->dev.dev, PAGE_SIZE,
- &sgbuf->addrs[i], wc);
+ p = do_alloc_pages(dmab->dev.dev, PAGE_SIZE, &sgbuf->addrs[i], wc);
if (!p)
goto error;
sgbuf->pages[i] = virt_to_page(p);
diff --git a/sound/core/memalloc_local.h b/sound/core/memalloc_local.h
index a6f3a87194da..8b19f3a68a4b 100644
--- a/sound/core/memalloc_local.h
+++ b/sound/core/memalloc_local.h
@@ -13,8 +13,4 @@ struct snd_malloc_ops {
void (*sync)(struct snd_dma_buffer *dmab, enum snd_dma_sync_mode mode);
};
-#ifdef CONFIG_SND_DMA_SGBUF
-extern const struct snd_malloc_ops snd_dma_sg_ops;
-#endif
-
#endif /* __MEMALLOC_LOCAL_H */
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 02df915eb3c6..ac2efeb63a39 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1237,12 +1237,12 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+ if (runtime->state == SNDRV_PCM_STATE_XRUN ||
+ runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG
pcm_dbg(substream->pcm,
"pcm_oss: write: recovering from %s\n",
- runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+ runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND");
#endif
ret = snd_pcm_oss_prepare(substream);
@@ -1257,7 +1257,7 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
break;
/* test, if we can't store new data, because the stream */
/* has not been started */
- if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
+ if (runtime->state == SNDRV_PCM_STATE_PREPARED)
return -EAGAIN;
}
return ret;
@@ -1269,18 +1269,18 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
snd_pcm_sframes_t delay;
int ret;
while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+ if (runtime->state == SNDRV_PCM_STATE_XRUN ||
+ runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG
pcm_dbg(substream->pcm,
"pcm_oss: read: recovering from %s\n",
- runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+ runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND");
#endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
if (ret < 0)
break;
- } else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
+ } else if (runtime->state == SNDRV_PCM_STATE_SETUP) {
ret = snd_pcm_oss_prepare(substream);
if (ret < 0)
break;
@@ -1293,7 +1293,7 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
frames, in_kernel);
mutex_lock(&runtime->oss.params_lock);
if (ret == -EPIPE) {
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
if (ret < 0)
break;
@@ -1312,12 +1312,12 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+ if (runtime->state == SNDRV_PCM_STATE_XRUN ||
+ runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG
pcm_dbg(substream->pcm,
"pcm_oss: writev: recovering from %s\n",
- runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+ runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND");
#endif
ret = snd_pcm_oss_prepare(substream);
@@ -1330,7 +1330,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
/* test, if we can't store new data, because the stream */
/* has not been started */
- if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
+ if (runtime->state == SNDRV_PCM_STATE_PREPARED)
return -EAGAIN;
}
return ret;
@@ -1341,18 +1341,18 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void *
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+ if (runtime->state == SNDRV_PCM_STATE_XRUN ||
+ runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG
pcm_dbg(substream->pcm,
"pcm_oss: readv: recovering from %s\n",
- runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+ runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND");
#endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
if (ret < 0)
break;
- } else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
+ } else if (runtime->state == SNDRV_PCM_STATE_SETUP) {
ret = snd_pcm_oss_prepare(substream);
if (ret < 0)
break;
@@ -1635,7 +1635,7 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
result = 0;
set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_lock_irq(substream);
- state = runtime->status->state;
+ state = runtime->state;
snd_pcm_stream_unlock_irq(substream);
if (state != SNDRV_PCM_STATE_RUNNING) {
set_current_state(TASK_RUNNING);
@@ -2854,8 +2854,8 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
struct snd_pcm_runtime *runtime = psubstream->runtime;
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(psubstream);
- if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
- (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
+ if (runtime->state != SNDRV_PCM_STATE_DRAINING &&
+ (runtime->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_playback_ready(psubstream)))
mask |= EPOLLOUT | EPOLLWRNORM;
snd_pcm_stream_unlock_irq(psubstream);
@@ -2865,7 +2865,7 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
snd_pcm_state_t ostate;
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(csubstream);
- ostate = runtime->status->state;
+ ostate = runtime->state;
if (ostate != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream))
mask |= EPOLLIN | EPOLLRDNORM;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 82925709fa12..9d95e3731123 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -387,7 +387,7 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "closed\n");
goto unlock;
}
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n");
goto unlock;
}
@@ -424,7 +424,7 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "closed\n");
goto unlock;
}
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n");
goto unlock;
}
@@ -970,7 +970,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
init_waitqueue_head(&runtime->sleep);
init_waitqueue_head(&runtime->tsleep);
- runtime->status->state = SNDRV_PCM_STATE_OPEN;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_OPEN);
mutex_init(&runtime->buffer_mutex);
atomic_set(&runtime->buffer_accessing, 0);
@@ -1112,7 +1112,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
if (snd_pcm_running(substream))
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
/* to be sure, set the state unconditionally */
- substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
+ __snd_pcm_set_state(substream->runtime,
+ SNDRV_PCM_STATE_DISCONNECTED);
wake_up(&substream->runtime->sleep);
wake_up(&substream->runtime->tsleep);
}
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 917c5b4f19d7..42c2ada8e888 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -295,7 +295,7 @@ static int snd_pcm_ioctl_xferi_compat(struct snd_pcm_substream *substream,
return -ENOTTY;
if (substream->stream != dir)
return -EINVAL;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (substream->runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (get_user(buf, &data32->buf) ||
@@ -341,7 +341,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
return -ENOTTY;
if (substream->stream != dir)
return -EINVAL;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (substream->runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
ch = substream->runtime->channels;
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 5b2ca028f5aa..494ec0c207fa 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -133,12 +133,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
static void dmaengine_pcm_dma_complete(void *arg)
{
+ unsigned int new_pos;
struct snd_pcm_substream *substream = arg;
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
- prtd->pos += snd_pcm_lib_period_bytes(substream);
- if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
- prtd->pos = 0;
+ new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream);
+ if (new_pos >= snd_pcm_lib_buffer_bytes(substream))
+ new_pos = 0;
+ prtd->pos = new_pos;
snd_pcm_period_elapsed(substream);
}
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 40751e5aff09..8b6aeb8a78f7 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -186,7 +186,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
avail = snd_pcm_avail(substream);
if (avail > runtime->avail_max)
runtime->avail_max = avail;
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
if (avail >= runtime->buffer_size) {
snd_pcm_drain_done(substream);
return -EPIPE;
@@ -1911,7 +1911,7 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream);
set_current_state(TASK_INTERRUPTIBLE);
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_SUSPENDED:
err = -ESTRPIPE;
goto _endloop;
@@ -2099,14 +2099,14 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream)
runtime = substream->runtime;
if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area))
return -EINVAL;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
return 0;
}
static int pcm_accessible_state(struct snd_pcm_runtime *runtime)
{
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PAUSED:
@@ -2225,7 +2225,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
goto _end_unlock;
runtime->twake = runtime->control->avail_min ? : 1;
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
+ if (runtime->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream);
/*
@@ -2233,7 +2233,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
* thread may start capture
*/
if (!is_playback &&
- runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
+ runtime->state == SNDRV_PCM_STATE_PREPARED &&
size >= runtime->start_threshold) {
err = snd_pcm_start(substream);
if (err < 0)
@@ -2247,7 +2247,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
snd_pcm_uframes_t cont;
if (!avail) {
if (!is_playback &&
- runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ runtime->state == SNDRV_PCM_STATE_DRAINING) {
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
goto _end_unlock;
}
@@ -2303,7 +2303,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
xfer += frames;
avail -= frames;
if (is_playback &&
- runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
+ runtime->state == SNDRV_PCM_STATE_PREPARED &&
snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
err = snd_pcm_start(substream);
if (err < 0)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ad0541e9e888..33769ca78cc8 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -595,8 +595,8 @@ static void snd_pcm_set_state(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
snd_pcm_stream_lock_irq(substream);
- if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
- substream->runtime->status->state = state;
+ if (substream->runtime->state != SNDRV_PCM_STATE_DISCONNECTED)
+ __snd_pcm_set_state(substream->runtime, state);
snd_pcm_stream_unlock_irq(substream);
}
@@ -724,7 +724,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
if (err < 0)
return err;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED:
@@ -889,7 +889,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (result < 0)
return result;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED:
if (atomic_read(&substream->mmap_count))
@@ -920,7 +920,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
return -ENXIO;
runtime = substream->runtime;
snd_pcm_stream_lock_irq(substream);
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_pcm_stream_unlock_irq(substream);
return -EBADFD;
}
@@ -1013,8 +1013,8 @@ int snd_pcm_status64(struct snd_pcm_substream *substream,
} else
runtime->audio_tstamp_report.valid = 1;
- status->state = runtime->status->state;
- status->suspended_state = runtime->status->suspended_state;
+ status->state = runtime->state;
+ status->suspended_state = runtime->suspended_state;
if (status->state == SNDRV_PCM_STATE_OPEN)
goto _end;
status->trigger_tstamp_sec = runtime->trigger_tstamp.tv_sec;
@@ -1148,7 +1148,7 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
channel = info->channel;
runtime = substream->runtime;
snd_pcm_stream_lock_irq(substream);
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_pcm_stream_unlock_irq(substream);
return -EBADFD;
}
@@ -1411,7 +1411,7 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
+ if (runtime->state != SNDRV_PCM_STATE_PREPARED)
return -EBADFD;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
!snd_pcm_playback_data(substream))
@@ -1444,7 +1444,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
runtime->hw_ptr_jiffies = jiffies;
runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) /
runtime->rate;
- runtime->status->state = state;
+ __snd_pcm_set_state(runtime, state);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
snd_pcm_playback_silence(substream, ULONG_MAX);
@@ -1485,7 +1485,7 @@ static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
runtime->trigger_master = substream;
return 0;
@@ -1506,9 +1506,9 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state != state) {
+ if (runtime->state != state) {
snd_pcm_trigger_tstamp(substream);
- runtime->status->state = state;
+ __snd_pcm_set_state(runtime, state);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
}
wake_up(&runtime->sleep);
@@ -1584,9 +1584,9 @@ static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
return -ENOSYS;
if (pause_pushed(state)) {
- if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
+ if (runtime->state != SNDRV_PCM_STATE_RUNNING)
return -EBADFD;
- } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
+ } else if (runtime->state != SNDRV_PCM_STATE_PAUSED)
return -EBADFD;
runtime->trigger_master = substream;
return 0;
@@ -1628,12 +1628,12 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
if (pause_pushed(state)) {
- runtime->status->state = SNDRV_PCM_STATE_PAUSED;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_PAUSED);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
wake_up(&runtime->sleep);
wake_up(&runtime->tsleep);
} else {
- runtime->status->state = SNDRV_PCM_STATE_RUNNING;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_RUNNING);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MCONTINUE);
}
}
@@ -1668,7 +1668,7 @@ static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_SUSPENDED:
return -EBUSY;
/* unresumable PCM state; return -EBUSY for skipping suspend */
@@ -1699,8 +1699,9 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
- runtime->status->suspended_state = runtime->status->state;
- runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
+ runtime->suspended_state = runtime->state;
+ runtime->status->suspended_state = runtime->suspended_state;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SUSPENDED);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSUSPEND);
wake_up(&runtime->sleep);
wake_up(&runtime->tsleep);
@@ -1791,8 +1792,8 @@ static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
if (runtime->trigger_master != substream)
return 0;
/* DMA not running previously? */
- if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING &&
- (runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING ||
+ if (runtime->suspended_state != SNDRV_PCM_STATE_RUNNING &&
+ (runtime->suspended_state != SNDRV_PCM_STATE_DRAINING ||
substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
return 0;
return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
@@ -1811,7 +1812,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
- runtime->status->state = runtime->status->suspended_state;
+ __snd_pcm_set_state(runtime, runtime->suspended_state);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
}
@@ -1848,7 +1849,7 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
int result;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_XRUN:
result = 0; /* already there */
break;
@@ -1871,7 +1872,7 @@ static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED:
@@ -1933,8 +1934,8 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
int f_flags = (__force int)state;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
if (snd_pcm_running(substream))
return -EBUSY;
@@ -1985,7 +1986,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
f_flags = substream->f_flags;
snd_pcm_stream_lock_irq(substream);
- switch (substream->runtime->status->state) {
+ switch (substream->runtime->state) {
case SNDRV_PCM_STATE_PAUSED:
snd_pcm_pause(substream, false);
fallthrough;
@@ -2009,7 +2010,7 @@ static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_DISCONNECTED:
case SNDRV_PCM_STATE_SUSPENDED:
@@ -2024,28 +2025,28 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_PREPARED:
/* start playback stream if possible */
if (! snd_pcm_playback_empty(substream)) {
snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
} else {
- runtime->status->state = SNDRV_PCM_STATE_SETUP;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SETUP);
}
break;
case SNDRV_PCM_STATE_RUNNING:
- runtime->status->state = SNDRV_PCM_STATE_DRAINING;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_DRAINING);
break;
case SNDRV_PCM_STATE_XRUN:
- runtime->status->state = SNDRV_PCM_STATE_SETUP;
+ __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SETUP);
break;
default:
break;
}
} else {
/* stop running stream */
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
+ if (runtime->state == SNDRV_PCM_STATE_RUNNING) {
snd_pcm_state_t new_state;
new_state = snd_pcm_capture_avail(runtime) > 0 ?
@@ -2055,7 +2056,7 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
}
}
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
+ if (runtime->state == SNDRV_PCM_STATE_DRAINING &&
runtime->trigger_master == substream &&
(runtime->hw.info & SNDRV_PCM_INFO_DRAIN_TRIGGER))
return substream->ops->trigger(substream,
@@ -2096,7 +2097,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
card = substream->pcm->card;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (file) {
@@ -2107,7 +2108,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream);
/* resume pause */
- if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
+ if (runtime->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, false);
/* pre-start/stop - all running streams are changed to DRAINING state */
@@ -2135,7 +2136,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
continue;
runtime = s->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
to_check = runtime;
break;
}
@@ -2174,7 +2175,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
break;
}
if (tout == 0) {
- if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
+ if (substream->runtime->state == SNDRV_PCM_STATE_SUSPENDED)
result = -ESTRPIPE;
else {
dev_dbg(substream->pcm->card->dev,
@@ -2206,13 +2207,13 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
snd_pcm_stream_lock_irq(substream);
/* resume pause */
- if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
+ if (runtime->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, false);
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
@@ -2275,8 +2276,8 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
snd_pcm_group_init(group);
down_write(&snd_pcm_link_rwsem);
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- substream->runtime->status->state != substream1->runtime->status->state ||
+ if (substream->runtime->state == SNDRV_PCM_STATE_OPEN ||
+ substream->runtime->state != substream1->runtime->state ||
substream->pcm->nonatomic != substream1->pcm->nonatomic) {
res = -EBADFD;
goto _end;
@@ -2700,7 +2701,7 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
snd_pcm_drop(substream);
if (substream->hw_opened) {
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
+ if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
do_hw_free(substream);
substream->ops->close(substream);
substream->hw_opened = 0;
@@ -2904,7 +2905,7 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
*/
static int do_pcm_hwsync(struct snd_pcm_substream *substream)
{
- switch (substream->runtime->status->state) {
+ switch (substream->runtime->state) {
case SNDRV_PCM_STATE_DRAINING:
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
return -EBADFD;
@@ -3203,7 +3204,7 @@ static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (put_user(0, &_xferi->result))
return -EFAULT;
@@ -3226,7 +3227,7 @@ static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream,
void *bufs;
snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (runtime->channels > 128)
return -EINVAL;
@@ -3290,7 +3291,7 @@ static int snd_pcm_common_ioctl(struct file *file,
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
res = snd_power_wait(substream->pcm->card);
@@ -3421,7 +3422,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
snd_pcm_uframes_t *frames = arg;
snd_pcm_sframes_t result;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
switch (cmd) {
@@ -3466,8 +3467,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
if (!frame_aligned(runtime, count))
return -EINVAL;
@@ -3491,8 +3492,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
if (!frame_aligned(runtime, count))
return -EINVAL;
@@ -3518,8 +3519,8 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
if (!iter_is_iovec(to))
return -EINVAL;
@@ -3555,8 +3556,8 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN ||
+ runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
if (!iter_is_iovec(from))
return -EINVAL;
@@ -3595,7 +3596,7 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
return ok | EPOLLERR;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return ok | EPOLLERR;
poll_wait(file, &runtime->sleep, wait);
@@ -3603,7 +3604,7 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
mask = 0;
snd_pcm_stream_lock_irq(substream);
avail = snd_pcm_avail(substream);
- switch (runtime->status->state) {
+ switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED:
@@ -3667,6 +3668,7 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
area->vm_ops = &snd_pcm_vm_ops_status;
area->vm_private_data = substream;
area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ area->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
return 0;
}
@@ -3874,7 +3876,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
return -EINVAL;
}
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
return -ENXIO;
@@ -3911,7 +3913,7 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
substream = pcm_file->substream;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
offset = area->vm_pgoff << PAGE_SHIFT;
@@ -3949,7 +3951,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ if (runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD;
return snd_fasync_helper(fd, file, on, &runtime->fasync);
}