From: Sergei Shtylylov <sshtylyov@ru.mvista.com>
To: linux-mips@linux-mips.org
Cc: Jordan Crouse <jordan.crouse@amd.com>
Subject: Re: [Alsa-devel] Au1550 OSS driver issues
Date: Thu, 08 Dec 2005 23:46:05 +0300 [thread overview]
Message-ID: <43989B8D.7050009@ru.mvista.com> (raw)
In-Reply-To: <43988C42.2060904@ru.mvista.com>
[-- Attachment #1: Type: text/plain, Size: 1817 bytes --]
Sergei Shtylylov wrote:
> Hello, I wrote:
>
>>> We have found some issues with Au1550 AC'97 OSS driver in 2.6
>>> (sound/oss/au1550_ac97.c), though it also should concern 2.4 driver
>>> (drivers/sound/au1550_psc.c).
> [au_readl() issue skipped]
>>> Second, start_dac() grabs a spinlock already held by its caller,
>>> au1550_write(). This doesn't show up with the standard UP spinlock
>>> impelmentation but when the different one (mutex based) is in use, a
>>> lockup happens. The second patch demonstates a possible solution but
>>> here's a question: why there's no "symmetric" spinlock logic in
>>> start_adc(), may be here exits another potential issue?
>
>
> Unfortunately, the proposed solution was incorrect for that mutex case
> because it was breaking the "critical section" by temporarily dropping the
> spinlock to call start_dac(). So, here's the updated version of that
> patch in
> which start_dac() and start_adc() don't grab the spinlocks anymore but
> their
> callers do instead.
>
>> After having a look at sound/oss/au1000.c,
>
>
> Now I don't think that this trick is always correct but since that
> driver
> is obsoleted by ALSA one I don't care that much. ;-)
>
>> here's an updated patch that deals with "nested" spinlocks the same
>> way that driver does, and adds spinlock to start_adc() as well.
>
>
> And the interrupt handlers also didn't grab the spinlock -- that's OK
> in the usual kernel but not when the IRQ handlers are threaded. So, they're
> grabbing the spinlock now (as every correct interrupt handler should do).
Failed to change the the subject and forgot about the sign-off, silly
me... :-(
WBR, Sergei
Signed-off-by: Konstantin Baidarov <kbaidarov@ru.mvista.com>
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
[-- Attachment #2: Au1550-AC97-OSS-spinlocks.patch --]
[-- Type: text/plain, Size: 3017 bytes --]
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index cdce915..f70effd 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -579,17 +579,15 @@ set_recv_slots(int num_channels)
} while ((stat & PSC_AC97STAT_DR) == 0);
}
+/* Hold spinlock for both start_dac() and start_adc() calls */
static void
start_dac(struct au1550_state *s)
{
struct dmabuf *db = &s->dma_dac;
- unsigned long flags;
if (!db->stopped)
return;
- spin_lock_irqsave(&s->lock, flags);
-
set_xmit_slots(db->num_channels);
au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
au_sync();
@@ -599,8 +597,6 @@ start_dac(struct au1550_state *s)
au1xxx_dbdma_start(db->dmanr);
db->stopped = 0;
-
- spin_unlock_irqrestore(&s->lock, flags);
}
static void
@@ -719,7 +715,6 @@ prog_dmabuf_dac(struct au1550_state *s)
}
-/* hold spinlock for the following */
static void
dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -727,6 +722,8 @@ dac_dma_interrupt(int irq, void *dev_id,
struct dmabuf *db = &s->dma_dac;
u32 ac97c_stat;
+ spin_lock(&s->lock);
+
ac97c_stat = au_readl(PSC_AC97STAT);
if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
@@ -748,6 +745,8 @@ dac_dma_interrupt(int irq, void *dev_id,
/* wake up anybody listening */
if (waitqueue_active(&db->wait))
wake_up(&db->wait);
+
+ spin_unlock(&s->lock);
}
@@ -759,6 +758,8 @@ adc_dma_interrupt(int irq, void *dev_id,
u32 obytes;
char *obuf;
+ spin_lock(&s->lock);
+
/* Pull the buffer from the dma queue.
*/
au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
@@ -766,6 +767,7 @@ adc_dma_interrupt(int irq, void *dev_id,
if ((dp->count + obytes) > dp->dmasize) {
/* Overrun. Stop ADC and log the error
*/
+ spin_unlock(&s->lock);
stop_adc(s);
dp->error++;
err("adc overrun");
@@ -788,6 +790,7 @@ adc_dma_interrupt(int irq, void *dev_id,
if (waitqueue_active(&dp->wait))
wake_up(&dp->wait);
+ spin_unlock(&s->lock);
}
static loff_t
@@ -1049,9 +1052,9 @@ au1550_read(struct file *file, char *buf
/* wait for samples in ADC dma buffer
*/
do {
+ spin_lock_irqsave(&s->lock, flags);
if (db->stopped)
start_adc(s);
- spin_lock_irqsave(&s->lock, flags);
avail = db->count;
if (avail <= 0)
__set_current_state(TASK_INTERRUPTIBLE);
@@ -1571,15 +1574,19 @@ au1550_ioctl(struct inode *inode, struct
if (get_user(val, (int *) arg))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
- if (val & PCM_ENABLE_INPUT)
+ if (val & PCM_ENABLE_INPUT) {
+ spin_lock_irqsave(&s->lock, flags);
start_adc(s);
- else
+ spin_unlock_irqrestore(&s->lock, flags);
+ } else
stop_adc(s);
}
if (file->f_mode & FMODE_WRITE) {
- if (val & PCM_ENABLE_OUTPUT)
+ if (val & PCM_ENABLE_OUTPUT) {
+ spin_lock_irqsave(&s->lock, flags);
start_dac(s);
- else
+ spin_unlock_irqrestore(&s->lock, flags);
+ } else
stop_dac(s);
}
return 0;
next prev parent reply other threads:[~2005-12-08 20:44 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-06 13:02 Au1550 OSS driver issues Sergei Shtylylov
2005-10-06 17:47 ` Dan Malek
2005-11-07 19:58 ` [Alsa-devel] " Sergei Shtylylov
2005-11-07 20:19 ` Lee Revell
2005-11-07 20:19 ` [Alsa-devel] " Lee Revell
2005-12-08 19:40 ` Sergei Shtylylov
2005-12-08 20:46 ` Sergei Shtylylov [this message]
2005-12-30 23:07 ` [PATCH] Au1xx0: replace casual readl() with au_readl() in the drivers Sergei Shtylylov
2005-12-31 4:11 ` Jordan Crouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43989B8D.7050009@ru.mvista.com \
--to=sshtylyov@ru.mvista.com \
--cc=jordan.crouse@amd.com \
--cc=linux-mips@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.