diff options
-rw-r--r-- | include/sound/pcm.h | 2 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 23 |
2 files changed, 16 insertions, 9 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index dd76cdede64d..83c6fa6aac43 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -313,7 +313,7 @@ struct snd_pcm_runtime { | |||
313 | struct snd_pcm_mmap_control *control; | 313 | struct snd_pcm_mmap_control *control; |
314 | 314 | ||
315 | /* -- locking / scheduling -- */ | 315 | /* -- locking / scheduling -- */ |
316 | unsigned int twake: 1; /* do transfer (!poll) wakeup */ | 316 | snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */ |
317 | wait_queue_head_t sleep; /* poll sleep */ | 317 | wait_queue_head_t sleep; /* poll sleep */ |
318 | wait_queue_head_t tsleep; /* transfer sleep */ | 318 | wait_queue_head_t tsleep; /* transfer sleep */ |
319 | struct fasync_struct *fasync; | 319 | struct fasync_struct *fasync; |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index e9d98be190c5..bcf95d3ff5c7 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -287,8 +287,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, | |||
287 | return -EPIPE; | 287 | return -EPIPE; |
288 | } | 288 | } |
289 | } | 289 | } |
290 | if (avail >= runtime->control->avail_min) | 290 | if (runtime->twake) { |
291 | wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); | 291 | if (avail >= runtime->twake) |
292 | wake_up(&runtime->tsleep); | ||
293 | } else if (avail >= runtime->control->avail_min) | ||
294 | wake_up(&runtime->sleep); | ||
292 | return 0; | 295 | return 0; |
293 | } | 296 | } |
294 | 297 | ||
@@ -1707,7 +1710,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed); | |||
1707 | * The available space is stored on availp. When err = 0 and avail = 0 | 1710 | * The available space is stored on availp. When err = 0 and avail = 0 |
1708 | * on the capture stream, it indicates the stream is in DRAINING state. | 1711 | * on the capture stream, it indicates the stream is in DRAINING state. |
1709 | */ | 1712 | */ |
1710 | static int wait_for_avail_min(struct snd_pcm_substream *substream, | 1713 | static int wait_for_avail(struct snd_pcm_substream *substream, |
1711 | snd_pcm_uframes_t *availp) | 1714 | snd_pcm_uframes_t *availp) |
1712 | { | 1715 | { |
1713 | struct snd_pcm_runtime *runtime = substream->runtime; | 1716 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1757,7 +1760,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, | |||
1757 | avail = snd_pcm_playback_avail(runtime); | 1760 | avail = snd_pcm_playback_avail(runtime); |
1758 | else | 1761 | else |
1759 | avail = snd_pcm_capture_avail(runtime); | 1762 | avail = snd_pcm_capture_avail(runtime); |
1760 | if (avail >= runtime->control->avail_min) | 1763 | if (avail >= runtime->twake) |
1761 | break; | 1764 | break; |
1762 | } | 1765 | } |
1763 | _endloop: | 1766 | _endloop: |
@@ -1820,7 +1823,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1820 | goto _end_unlock; | 1823 | goto _end_unlock; |
1821 | } | 1824 | } |
1822 | 1825 | ||
1823 | runtime->twake = 1; | 1826 | runtime->twake = runtime->control->avail_min ? : 1; |
1824 | while (size > 0) { | 1827 | while (size > 0) { |
1825 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 1828 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
1826 | snd_pcm_uframes_t avail; | 1829 | snd_pcm_uframes_t avail; |
@@ -1833,7 +1836,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | |||
1833 | err = -EAGAIN; | 1836 | err = -EAGAIN; |
1834 | goto _end_unlock; | 1837 | goto _end_unlock; |
1835 | } | 1838 | } |
1836 | err = wait_for_avail_min(substream, &avail); | 1839 | runtime->twake = min_t(snd_pcm_uframes_t, size, |
1840 | runtime->control->avail_min ? : 1); | ||
1841 | err = wait_for_avail(substream, &avail); | ||
1837 | if (err < 0) | 1842 | if (err < 0) |
1838 | goto _end_unlock; | 1843 | goto _end_unlock; |
1839 | } | 1844 | } |
@@ -2042,7 +2047,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2042 | goto _end_unlock; | 2047 | goto _end_unlock; |
2043 | } | 2048 | } |
2044 | 2049 | ||
2045 | runtime->twake = 1; | 2050 | runtime->twake = runtime->control->avail_min ? : 1; |
2046 | while (size > 0) { | 2051 | while (size > 0) { |
2047 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 2052 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
2048 | snd_pcm_uframes_t avail; | 2053 | snd_pcm_uframes_t avail; |
@@ -2060,7 +2065,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2060 | err = -EAGAIN; | 2065 | err = -EAGAIN; |
2061 | goto _end_unlock; | 2066 | goto _end_unlock; |
2062 | } | 2067 | } |
2063 | err = wait_for_avail_min(substream, &avail); | 2068 | runtime->twake = min_t(snd_pcm_uframes_t, size, |
2069 | runtime->control->avail_min ? : 1); | ||
2070 | err = wait_for_avail(substream, &avail); | ||
2064 | if (err < 0) | 2071 | if (err < 0) |
2065 | goto _end_unlock; | 2072 | goto _end_unlock; |
2066 | if (!avail) | 2073 | if (!avail) |