} else {
if (new_hw_ptr == ULONG_MAX) { /* initialization */
snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
+ if (avail > runtime->buffer_size)
+ avail = runtime->buffer_size;
runtime->silence_filled = avail > 0 ? avail : 0;
runtime->silence_start = (runtime->status->hw_ptr +
runtime->silence_filled) %
return -EPIPE;
}
}
- if (avail >= runtime->control->avail_min)
- wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
+ if (runtime->twake) {
+ if (avail >= runtime->twake)
+ wake_up(&runtime->tsleep);
+ } else if (avail >= runtime->control->avail_min)
+ wake_up(&runtime->sleep);
return 0;
}
* The available space is stored on availp. When err = 0 and avail = 0
* on the capture stream, it indicates the stream is in DRAINING state.
*/
-static int wait_for_avail_min(struct snd_pcm_substream *substream,
+static int wait_for_avail(struct snd_pcm_substream *substream,
snd_pcm_uframes_t *availp)
{
struct snd_pcm_runtime *runtime = substream->runtime;
avail = snd_pcm_playback_avail(runtime);
else
avail = snd_pcm_capture_avail(runtime);
- if (avail >= runtime->control->avail_min)
+ if (avail >= runtime->twake)
break;
}
_endloop:
goto _end_unlock;
}
- runtime->twake = 1;
+ runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
err = -EAGAIN;
goto _end_unlock;
}
- err = wait_for_avail_min(substream, &avail);
+ runtime->twake = min_t(snd_pcm_uframes_t, size,
+ runtime->control->avail_min ? : 1);
+ err = wait_for_avail(substream, &avail);
if (err < 0)
goto _end_unlock;
}
goto _end_unlock;
}
- runtime->twake = 1;
+ runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
err = -EAGAIN;
goto _end_unlock;
}
- err = wait_for_avail_min(substream, &avail);
+ runtime->twake = min_t(snd_pcm_uframes_t, size,
+ runtime->control->avail_min ? : 1);
+ err = wait_for_avail(substream, &avail);
if (err < 0)
goto _end_unlock;
if (!avail)