Takashi Iwai wrote:
So, the PCM status is properly changed to XRUN as expected. From the driver perspective, everything must be fine.
I've been debugging aplay. The main loop is function pcm_write(). It calls writei_func() which returns -EPIPE. This causes aplay to jump to xrun(), which attempts to recover.
This is not what I want. I don't want to return overrun/underrun. I want to return failure. Returning XRUN is wrong.
Instead, I need to take a look at this code I have:
snd_pcm_stream_lock_irqsave(substream, flags);
if (snd_pcm_running(substream)) snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(substream, flags);
It's the call to snd_pcm_stop() that I don't like. There doesn't appear to be a SNDRV_PCM_STATE_xxx state that makes sense. This function should eventually bring me to snd_pcm_pre_stop(). But this function returns -EBADFD because the current state is RUNNING and not OPEN. Because it returns an error, snd_pcm_do_stop() is never called.
This doesn't make any sense to me. Why should I be able to stop a stream only if it's open but not running? If it's open, but not running, then there's nothing to stop! Can you explain the restriction in snd_pcm_pre_stop()?