On Fri, 16 Nov 2007, Takashi Iwai wrote:
At Thu, 15 Nov 2007 14:28:14 -0600, Timur Tabi wrote:
Takashi Iwai wrote:
At Thu, 15 Nov 2007 09:00:54 -0600, Timur Tabi wrote:
Jaroslav Kysela wrote:
Yes, call snd_pcm_stop() function. The call must be protected with snd_pcm_stream_lock... See to i2c/other/ak4117.c for an example.
That code calls snd_pcm_stop() from a timer, not an ISR. Do I need the call to wake_up() as well?
snd_pcm_stop() can be called from ISR, too (e.g. snd_pcm_period_elapsed() may call snd_pcm_stop() when XRUN occurs). You only need to protect it via snd_pcm_stream_lock*().
It doesn't seem to do much. Here's the function I wrote:
static void fsl_dma_abort_stream(struct snd_pcm_substream *substream) { unsigned long flags;
snd_pcm_stream_lock_irqsave(substream, flags); if (snd_pcm_running(substream)) { snd_pcm_stop(substream, SNDRV_PCM_STATE_DRAINING);
You passed a wrong state. Usually snd_pcm_stop() passes either SNDRV_PCM_STATE_SETUP (for post-draining) or SNDRV_PCM_STATE_XRUN (for errors).
wake_up(&substream->runtime->sleep);
} snd_pcm_stream_unlock_irqrestore(substream, flags); }
This wake_up is superfluous. Now I understand your question in the last mail...
I'm not sure if the wake call is superfluous, if driver ends to call elapsed callbacks, there is no way to wakeup process when it sleeps somewhere. I think that code might be covered with a nice macro with a name like 'snd_pcm_hw_stopped()' or so.
Jaroslav
----- Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project