Skip to content

Commit

Permalink
Merge branch 'fix/pcm-jiffies-check' into for-linus
Browse files Browse the repository at this point in the history
* fix/pcm-jiffies-check:
  ALSA: Enable PCM hw_ptr_jiffies check only in xrun_debug mode
  ALSA: Fix invalid jiffies check after pause
  • Loading branch information
Takashi Iwai committed May 27, 2009
2 parents f00452c + c87d973 commit f5219b6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Documentation/sound/alsa/Procfile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ card*/pcm*/xrun_debug
When this value is greater than 1, the driver will show the
stack trace additionally. This may help the debugging.

Since 2.6.30, this option also enables the hwptr check using
jiffies. This detects spontaneous invalid pointer callback
values, but can be lead to too much corrections for a (mostly
buggy) hardware that doesn't give smooth pointer updates.

card*/pcm*/sub*/info
The general information of this PCM sub-stream.

Expand Down
10 changes: 8 additions & 2 deletions sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;
}
}

/* Do jiffies check only in xrun_debug mode */
if (!xrun_debug(substream))
goto no_jiffies_check;

/* Skip the jiffies check for hardwares with BATCH flag.
* Such hardware usually just increases the position at each IRQ,
* thus it can't give any strange position.
Expand Down Expand Up @@ -336,7 +341,9 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
/* Do jiffies check only in xrun_debug mode */
if (xrun_debug(substream) &&
((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
Expand Down Expand Up @@ -1478,7 +1485,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
runtime->status->hw_ptr %= runtime->buffer_size;
else
runtime->status->hw_ptr = 0;
runtime->hw_ptr_jiffies = jiffies;
snd_pcm_stream_unlock_irqrestore(substream, flags);
return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
runtime->hw_ptr_jiffies = jiffies;
runtime->status->state = state;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
Expand Down Expand Up @@ -961,6 +962,11 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
{
if (substream->runtime->trigger_master != substream)
return 0;
/* The jiffies check in snd_pcm_update_hw_ptr*() is done by
* a delta betwen the current jiffies, this gives a large enough
* delta, effectively to skip the check once.
*/
substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
return substream->ops->trigger(substream,
push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
Expand Down

0 comments on commit f5219b6

Please sign in to comment.