[alsa-devel] Handling HDA FIFO error
Daniel Drake
dsd at laptop.org
Sat May 25 16:08:14 CEST 2013
On Wed, May 15, 2013 at 4:08 AM, Takashi Iwai <tiwai at suse.de> wrote:
> At Wed, 15 May 2013 11:08:55 +0200,
> Clemens Ladisch wrote:
>> Daniel Drake wrote:
>> > Digging into the HDA code, I can see that normally, when the stream
>> > gets started, we get interrupts with SD_STS as 0x24. In the failure
>> > case, as soon as we start the stream, we get a flood of interrupts
>> > with SD_STS 0x8 - which indicates FIFO error.
>> >
>> > Disabling interrupt generation upon FIFO error does not help much - it
>> > avoids the flood of interrupts, but doesn't change the fact that audio
>> > playing apps hang or loop infinitely.
>> >
>> > Are there any things I could check that would explain why a FIFO error
>> > might be occurring?
>>
>> Probably a buffer underrun, i.e., the controller did not manage to
>> read samples from memory fast enough.
That would seem logical, but I don't think this can be happening here.
In this case the audio buffer is filled up with data before playback
is started, and it only auto-starts right at the point when the buffer
becomes full. Then immediately, the first interrupt that comes in says
"FIFO error". The buffer was full at this point.
However I was unable to reproduce this FIFO error interrupt when
revisiting the problem. Every time I go back to it with my test case
of calling gst-launch in a loop, a different audio-related problem
seems to pop up.
Digging further, I found some oddness with the device being powered up
and down at the wrong times. I'm on Linux-3.3 here, so I threw in a
load of the newer commits that fix the CONFIG_SND_HDA_POWER_SAVE
functionality and now things seem to be working perfectly. Sorry for
the noise and thanks for already having fixed this :)
Here is a patch anyway which could be used to handle the FIFO error
interrupt. It hasn't reappeared so I haven't been able to test it.
Thanks,
Daniel
-------------- next part --------------
From ba057abe909df7e2b9fba57e0db989e7ea47951b Mon Sep 17 00:00:00 2001
From: Daniel Drake <dsd at laptop.org>
Date: Tue, 21 May 2013 13:02:39 -0600
Subject: [PATCH] ALSA: HDA: handle FIFO errors
The HDA code was listening for the FIFO error interrupt but not handling
it. Such condition would tend to indicate an xrun.
On OLPC XO-1.75 (VIA VX855) this interrupt seems to be erroneously raised
on occasion, resulting in a halt of sound playback and the application
hanging as no sound buffer space becomes available.
Signed-off-by: Daniel Drake <dsd at laptop.org>
---
sound/pci/hda/hda_intel.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index de65fa8..c3ef376 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1237,8 +1237,20 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
if (status & azx_dev->sd_int_sta_mask) {
sd_status = azx_sd_readb(azx_dev, SD_STS);
azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
- if (!azx_dev->substream || !azx_dev->running ||
- !(sd_status & SD_INT_COMPLETE))
+ if (!azx_dev->substream || !azx_dev->running)
+ continue;
+
+ if (sd_status & SD_INT_FIFO_ERR) {
+ snd_pcm_stream_lock(azx_dev->substream);
+ spin_unlock(&chip->reg_lock);
+ snd_pcm_stop(azx_dev->substream,
+ SNDRV_PCM_STATE_XRUN);
+ spin_lock(&chip->reg_lock);
+ snd_pcm_stream_unlock(azx_dev->substream);
+ continue;
+ }
+
+ if (!(sd_status & SD_INT_COMPLETE))
continue;
/* check whether this IRQ is really acceptable */
ok = azx_position_ok(chip, azx_dev);
--
1.8.1.4
More information about the Alsa-devel
mailing list