Hi David,
Just wondering... did the fix you suggested below permanently fix the audio
write stall problem? For our project, we're now at the point in which we're
fixing issues we put hold on when we first started our code development; one of
these issues is the write (and read) stall problems we were seeing; we
currently have audio write and read stall detection and recovery logic in our
code that when the stall occurs, we reset and re-initialize the audio device,
which fixes the problem; unfortunately, this means we loose audio for 3-5
seconds. For your solution to problem 1, do you mean "place the #if 0, #endif
around the whole if scope" like this:
#if 0
if (AUDIO_QUEUE_LAST(s)) {
audio_stream_t *s = data;
audio_buf_t *b = &s->buffers[s->dma_tail];
if (s->dma_spinref > 0) {
s->dma_spinref--;
} else if (!s->buffers) {
DPRINTK
("davinci_audio: received DMA IRQ for non\
existent buffers!\n");
return;
} else if (b->dma_ref && --b->dma_ref == 0 &&
b->offset >= s->fragsize) {
/* This fragment is done */
b->offset = 0;
s->bytecount += s->fragsize;
s->fragcount++;
s->dma_spinref = -s->dma_spinref;
if (++s->dma_tail >= s->nbfrags)
s->dma_tail = 0;
if (!s->mapped) {
complete(&s->wfc);
} else
s->pending_frags++;
wake_up(&s->wq);
}
AUDIO_INCREMENT_HEAD(s);
audio_stop_dma(s);
return;
}
#endif
I tried your fix along with the solution to problem 2 and I'm getting some
weird residue sound in which the last fragment of the audio is played repeatly
several times (5-10 times) after play a short wav file. Do you have any new
updates/fixes that you can share? Thanks in advance.
Regards,
Andy
----- Original Message ----
From: David A Kondrad <[EMAIL PROTECTED]>
To: [email protected]
Sent: Monday, January 14, 2008 1:21:39 PM
Subject: OSS audio driver under-run breakthrough
Greetings,
I've seen quite a few posts regarding lockups with the audio driver,
especially on under-run conditions and closing (also related to under-run).
Most people were tracking it down to DMA register errors and such, but I
believe those were symptoms of a larger problem.
We have a system that plays intercom announce tones (for talking,
hands-free, etc) as well as door chimes.
Our approach was to open the sound device at the beginning of the program
and start a thread that processed sound requests and
pumped the data out to /dev/dsp. This all sounds resonable, except that the
audio output thread would lock up inside write after a few sound requests.
As a note, we're currently using the supported montavista 2.6.10 with all
current MV patches applied, but I found the exact same code inside the
2.6.23 kernel.
Turning on kernel debugging and dumping the audio driver dma context
information we noticed a few very strange things related to the lockup:
1. We were occasionally getting "Called again while In Use" kmsg's from
audio_process_dma (davinci-audio-dma-intfc.c)
The only way this could happen is if the ISR tried to get inside that
function while the DSR was working on it.
2. When audio would freeze we would see that the dma queue was always full.
This led me to believe that someone wasn't waking up the next DMA
transfer in line.
Problem 1:
----------
After many iterations of adding more debug messages and playing a sound
file with different write sizes and thread sleep times,
I found the culprit to be the code inside the following if statement:
File : davinci-audio-dma-intfc.c:
Func: sound_dma_irq_handler
All the comments in the file point toward using delayed-service-routine
tasklets to process any queue requests, which this code violates by
processing it in the ISR instead of firing off the DSR.
That code doesn't belong there and in fact messes up the audio driver
state.
Solution:
---------
Surround the entire if statement with:
#if 0
if(AUDIO_QUEUE_LAST(s)) {
// Code omitted (processes a queue request then returns)
}
#endif
Problem 2:
----------
File: davinci-audio-dma-intfc.c
Func: audio_dsr_handler
// snip
if(AUDIO_QUEUE_EMPTY(s)) {
// snip
AUDIO_INCREMENT_HEAD(s); /* Empty the queue */
// snip
}
The severe issue here is that the queue is already empty (s->dma_q_count ==
0) and AUDIO_INCREMENT_HEAD(s) has the side effect of decrementing
dma_q_count.
Solution:
---------
The fix is to comment out AUDIO_INCREMENT_HEAD(s) inside that if-statement
to ensure that the dma_q_count does not drop below 0.
Problem 3:
----------
If the AIC33 driver is configured as AIC33_MASTER, the audio sounds like it
is being played at 1/2 sampling rate or slower.
There was a hack posted at one time to the official 2.6.10 source that
fixed this for the DVEVM, but the drivers in 2.6.23 were reworked and I
couldn't find a nice way to apply them.
Solution: ???
---------
The only thing I can do at moment to get rid of this problem is to use the
AIC33 as a slave to the McBSP.
I have a feeling that it is going to cause me trouble when we move to our
target board which has 2 AIC33's tied to the same McBSP.
Speaking of which, anybody use multiple AIC33's in a davinci design?
Summary:
With the changes I listed, we are now able to run our test app without
locking up the /dev/dsp device regardless of the artificial latencies
introduced.
I'm not familiar with the patching protocol (although I've garnered a
little bit off of the exchanges with the NAND driver), but is this
something that should be submitted to the 2.6.23 git?
Regards,
David
DAVID A. KONDRAD
Software Design Engineer
On-Q/Legrand
www.onqlegrand.com
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source