diff options
| -rw-r--r-- | include/sound/pcm.h | 5 | ||||
| -rw-r--r-- | sound/core/pcm.c | 1 | ||||
| -rw-r--r-- | sound/core/pcm_lib.c | 20 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 3 |
4 files changed, 17 insertions, 12 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index e26fb3c58037..3bc9bca771ec 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
| @@ -311,8 +311,9 @@ struct snd_pcm_runtime { | |||
| 311 | struct snd_pcm_mmap_control *control; | 311 | struct snd_pcm_mmap_control *control; |
| 312 | 312 | ||
| 313 | /* -- locking / scheduling -- */ | 313 | /* -- locking / scheduling -- */ |
| 314 | unsigned int nowake: 1; /* no wakeup (data-copy in progress) */ | 314 | unsigned int twake: 1; /* do transfer (!poll) wakeup */ |
| 315 | wait_queue_head_t sleep; | 315 | wait_queue_head_t sleep; /* poll sleep */ |
| 316 | wait_queue_head_t tsleep; /* transfer sleep */ | ||
| 316 | struct fasync_struct *fasync; | 317 | struct fasync_struct *fasync; |
| 317 | 318 | ||
| 318 | /* -- private section -- */ | 319 | /* -- private section -- */ |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index df57a0e30bf2..0d428d0896db 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
| @@ -894,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
| 894 | memset((void*)runtime->control, 0, size); | 894 | memset((void*)runtime->control, 0, size); |
| 895 | 895 | ||
| 896 | init_waitqueue_head(&runtime->sleep); | 896 | init_waitqueue_head(&runtime->sleep); |
| 897 | init_waitqueue_head(&runtime->tsleep); | ||
| 897 | 898 | ||
| 898 | runtime->status->state = SNDRV_PCM_STATE_OPEN; | 899 | runtime->status->state = SNDRV_PCM_STATE_OPEN; |
| 899 | 900 | ||
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 5417f7dce834..e2a817eac2a9 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
| @@ -285,8 +285,8 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, | |||
| 285 | return -EPIPE; | 285 | return -EPIPE; |
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | if (!runtime->nowake && avail >= runtime->control->avail_min) | 288 | if (avail >= runtime->control->avail_min) |
| 289 | wake_up(&runtime->sleep); | 289 | wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); |
| 290 | return 0; | 290 | return 0; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| @@ -1692,7 +1692,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, | |||
| 1692 | long tout; | 1692 | long tout; |
| 1693 | 1693 | ||
| 1694 | init_waitqueue_entry(&wait, current); | 1694 | init_waitqueue_entry(&wait, current); |
| 1695 | add_wait_queue(&runtime->sleep, &wait); | 1695 | add_wait_queue(&runtime->tsleep, &wait); |
| 1696 | for (;;) { | 1696 | for (;;) { |
| 1697 | if (signal_pending(current)) { | 1697 | if (signal_pending(current)) { |
| 1698 | err = -ERESTARTSYS; | 1698 | err = -ERESTARTSYS; |
| @@ -1735,7 +1735,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, | |||
| 1735 | break; | 1735 | break; |
| 1736 | } | 1736 | } |
| 1737 | _endloop: | 1737 | _endloop: |
| 1738 | remove_wait_queue(&runtime->sleep, &wait); | 1738 | remove_wait_queue(&runtime->tsleep, &wait); |
| 1739 | *availp = avail; | 1739 | *availp = avail; |
| 1740 | return err; | 1740 | return err; |
| 1741 | } | 1741 | } |
| @@ -1794,7 +1794,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
| 1794 | goto _end_unlock; | 1794 | goto _end_unlock; |
| 1795 | } | 1795 | } |
| 1796 | 1796 | ||
| 1797 | runtime->nowake = 1; | 1797 | runtime->twake = 1; |
| 1798 | while (size > 0) { | 1798 | while (size > 0) { |
| 1799 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 1799 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
| 1800 | snd_pcm_uframes_t avail; | 1800 | snd_pcm_uframes_t avail; |
| @@ -1816,7 +1816,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
| 1816 | if (frames > cont) | 1816 | if (frames > cont) |
| 1817 | frames = cont; | 1817 | frames = cont; |
| 1818 | if (snd_BUG_ON(!frames)) { | 1818 | if (snd_BUG_ON(!frames)) { |
| 1819 | runtime->nowake = 0; | 1819 | runtime->twake = 0; |
| 1820 | snd_pcm_stream_unlock_irq(substream); | 1820 | snd_pcm_stream_unlock_irq(substream); |
| 1821 | return -EINVAL; | 1821 | return -EINVAL; |
| 1822 | } | 1822 | } |
| @@ -1855,7 +1855,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
| 1855 | } | 1855 | } |
| 1856 | } | 1856 | } |
| 1857 | _end_unlock: | 1857 | _end_unlock: |
| 1858 | runtime->nowake = 0; | 1858 | runtime->twake = 0; |
| 1859 | if (xfer > 0 && err >= 0) | 1859 | if (xfer > 0 && err >= 0) |
| 1860 | snd_pcm_update_state(substream, runtime); | 1860 | snd_pcm_update_state(substream, runtime); |
| 1861 | snd_pcm_stream_unlock_irq(substream); | 1861 | snd_pcm_stream_unlock_irq(substream); |
| @@ -2016,7 +2016,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
| 2016 | goto _end_unlock; | 2016 | goto _end_unlock; |
| 2017 | } | 2017 | } |
| 2018 | 2018 | ||
| 2019 | runtime->nowake = 1; | 2019 | runtime->twake = 1; |
| 2020 | while (size > 0) { | 2020 | while (size > 0) { |
| 2021 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 2021 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
| 2022 | snd_pcm_uframes_t avail; | 2022 | snd_pcm_uframes_t avail; |
| @@ -2045,7 +2045,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
| 2045 | if (frames > cont) | 2045 | if (frames > cont) |
| 2046 | frames = cont; | 2046 | frames = cont; |
| 2047 | if (snd_BUG_ON(!frames)) { | 2047 | if (snd_BUG_ON(!frames)) { |
| 2048 | runtime->nowake = 0; | 2048 | runtime->twake = 0; |
| 2049 | snd_pcm_stream_unlock_irq(substream); | 2049 | snd_pcm_stream_unlock_irq(substream); |
| 2050 | return -EINVAL; | 2050 | return -EINVAL; |
| 2051 | } | 2051 | } |
| @@ -2078,7 +2078,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
| 2078 | xfer += frames; | 2078 | xfer += frames; |
| 2079 | } | 2079 | } |
| 2080 | _end_unlock: | 2080 | _end_unlock: |
| 2081 | runtime->nowake = 0; | 2081 | runtime->twake = 0; |
| 2082 | if (xfer > 0 && err >= 0) | 2082 | if (xfer > 0 && err >= 0) |
| 2083 | snd_pcm_update_state(substream, runtime); | 2083 | snd_pcm_update_state(substream, runtime); |
| 2084 | snd_pcm_stream_unlock_irq(substream); | 2084 | snd_pcm_stream_unlock_irq(substream); |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 27284f628361..56ec35e8510b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -919,6 +919,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) | |||
| 919 | runtime->status->state = state; | 919 | runtime->status->state = state; |
| 920 | } | 920 | } |
| 921 | wake_up(&runtime->sleep); | 921 | wake_up(&runtime->sleep); |
| 922 | wake_up(&runtime->tsleep); | ||
| 922 | } | 923 | } |
| 923 | 924 | ||
| 924 | static struct action_ops snd_pcm_action_stop = { | 925 | static struct action_ops snd_pcm_action_stop = { |
| @@ -1004,6 +1005,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push) | |||
| 1004 | SNDRV_TIMER_EVENT_MPAUSE, | 1005 | SNDRV_TIMER_EVENT_MPAUSE, |
| 1005 | &runtime->trigger_tstamp); | 1006 | &runtime->trigger_tstamp); |
| 1006 | wake_up(&runtime->sleep); | 1007 | wake_up(&runtime->sleep); |
| 1008 | wake_up(&runtime->tsleep); | ||
| 1007 | } else { | 1009 | } else { |
| 1008 | runtime->status->state = SNDRV_PCM_STATE_RUNNING; | 1010 | runtime->status->state = SNDRV_PCM_STATE_RUNNING; |
| 1009 | if (substream->timer) | 1011 | if (substream->timer) |
| @@ -1061,6 +1063,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) | |||
| 1061 | runtime->status->suspended_state = runtime->status->state; | 1063 | runtime->status->suspended_state = runtime->status->state; |
| 1062 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; | 1064 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; |
| 1063 | wake_up(&runtime->sleep); | 1065 | wake_up(&runtime->sleep); |
| 1066 | wake_up(&runtime->tsleep); | ||
| 1064 | } | 1067 | } |
| 1065 | 1068 | ||
| 1066 | static struct action_ops snd_pcm_action_suspend = { | 1069 | static struct action_ops snd_pcm_action_suspend = { |
