#define xrun_debug(substream, mask) \
((substream)->pstr->xrun_debug & (mask))
+#else
+#define xrun_debug(substream, mask) 0
+#endif
#define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
}
}
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#define hw_ptr_error(substream, fmt, args...) \
do { \
if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
-#define xrun_debug(substream, mask) 0
-#define xrun(substream) do { } while (0)
#define hw_ptr_error(substream, fmt, args...) do { } while (0)
#define xrun_log(substream, pos) do { } while (0)
#define xrun_log_show(substream) do { } while (0)
return -EPIPE;
}
}
- if (!runtime->nowake && avail >= runtime->control->avail_min)
- wake_up(&runtime->sleep);
+ if (avail >= runtime->control->avail_min)
+ wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
return 0;
}
if (in_interrupt) {
/* we know that one period was processed */
/* delta = "expected next hw_ptr" for in_interrupt != 0 */
- delta = old_hw_ptr - (old_hw_ptr % runtime->period_size)
- + runtime->period_size;
+ delta = runtime->hw_ptr_interrupt + runtime->period_size;
if (delta > new_hw_ptr) {
hw_base += runtime->buffer_size;
if (hw_base >= runtime->boundary)
runtime->silence_size > 0)
snd_pcm_playback_silence(substream, new_hw_ptr);
+ if (in_interrupt) {
+ delta = new_hw_ptr - runtime->hw_ptr_interrupt;
+ if (delta < 0)
+ delta += runtime->boundary;
+ delta -= (snd_pcm_uframes_t)delta % runtime->period_size;
+ runtime->hw_ptr_interrupt += delta;
+ if (runtime->hw_ptr_interrupt >= runtime->boundary)
+ runtime->hw_ptr_interrupt -= runtime->boundary;
+ }
runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;
long tout;
init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
+ add_wait_queue(&runtime->tsleep, &wait);
for (;;) {
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
}
_endloop:
- remove_wait_queue(&runtime->sleep, &wait);
+ remove_wait_queue(&runtime->tsleep, &wait);
*availp = avail;
return err;
}
goto _end_unlock;
}
- runtime->nowake = 1;
+ runtime->twake = 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
if (frames > cont)
frames = cont;
if (snd_BUG_ON(!frames)) {
- runtime->nowake = 0;
+ runtime->twake = 0;
snd_pcm_stream_unlock_irq(substream);
return -EINVAL;
}
}
}
_end_unlock:
- runtime->nowake = 0;
+ runtime->twake = 0;
if (xfer > 0 && err >= 0)
snd_pcm_update_state(substream, runtime);
snd_pcm_stream_unlock_irq(substream);
goto _end_unlock;
}
- runtime->nowake = 1;
+ runtime->twake = 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
if (frames > cont)
frames = cont;
if (snd_BUG_ON(!frames)) {
- runtime->nowake = 0;
+ runtime->twake = 0;
snd_pcm_stream_unlock_irq(substream);
return -EINVAL;
}
xfer += frames;
}
_end_unlock:
- runtime->nowake = 0;
+ runtime->twake = 0;
if (xfer > 0 && err >= 0)
snd_pcm_update_state(substream, runtime);
snd_pcm_stream_unlock_irq(substream);