[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.

-------------- 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,
+				spin_lock(&chip->reg_lock);
+				snd_pcm_stream_unlock(azx_dev->substream);
+				continue;
+			}
+			if (!(sd_status & SD_INT_COMPLETE))
 			/* check whether this IRQ is really acceptable */
 			ok = azx_position_ok(chip, azx_dev);

More information about the Alsa-devel mailing list