Thanks for that report, it was just what I needed. I was already tracking the various code responsible for updating posbuf and your trace has confirmed some of what I was expecting. There are several reasons why posbuf/pos won't be updated so we should try eliminating possibilities.
In snd_pcm_update_hw_ptr_pos() it is possible that a buffer over-run (XRUN) could prevent pos being updated:
Thanks for that report, it was just what I needed. I was already tracking the various code responsible for updating posbuf and your trace has confirmed some of what I was expecting. There are several reasons why posbuf/pos won't be updated so we should try eliminating possibilities.
In snd_pcm_ update_ hw_ptr_ pos() it is possible that a buffer over-run (XRUN) could prevent pos being updated:
pos = substream- >ops->pointer( substream) ;
if (pos == SNDRV_PCM_POS_XRUN)
return pos; /* XRUN */
Because if the function didn't return at that point it would update pos:
pos -= pos % runtime->min_align;
Using CONFIG_ SND_PCM_ XRUN_DEBUG, in snd_pcm_ update_ hw_ptr_ interrupt( ) we might see something useful from:
#ifdef CONFIG_ SND_PCM_ XRUN_DEBUG >pstr-> xrun_debug) { printd( KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime- >buffer_ size / 2); >pstr-> xrun_debug > 1)
if (runtime->periods > 1 && substream-
snd_
if (substream-
dump_stack();
}
#endif
assuming that the function didn't return before it got to that point:
pos = snd_pcm_ update_ hw_ptr_ pos(substream, runtime);
if (pos == SNDRV_PCM_POS_XRUN) {
xrun(substream);
return -EPIPE;
}
Alternatively, we need to watch snd_pcm_ update_ hw_ptr_ interrupt( ) where control can branch:
if (runtime- >period_ size == runtime- >buffer_ size) >hw_ptr_ base + pos; >hw_ptr_ interrupt + runtime- >period_ size;
goto __next_buf;
new_hw_ptr = runtime-
hw_ptr_interrupt = runtime-