ChangeSet 1.2181.25.19, 2005/03/22 09:06:46+01:00, [EMAIL PROTECTED]
[ALSA] fix P16V breakage for non Audigy2 cards
EMU10K1/EMU10K2 driver
The P16V patch unconditionally checks the IPR2 register in the interrupt
handler resulting in infinite loop and system lockup on any non Audigy2
cards. I really hate checking emu->is_audigy and emu->revision in a
fast path like the IRQ handler but I don't see another way.
Also, don't bother allocating/freeing the DMA buffer for P16V unless
it's really present.
This is a critical fix and should trigger an immediate rc2 release IMO.
Currently any emu10k1 users other than Audigy 2 will lock up hard as
soon as they play any sound.
Signed-off-by: Lee Revell <[EMAIL PROTECTED]>
Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>
emu10k1.c | 8 +++++---
emu10k1_main.c | 3 ++-
irq.c | 23 ++++++++++++-----------
3 files changed, 19 insertions(+), 15 deletions(-)
diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
--- a/sound/pci/emu10k1/emu10k1.c 2005-03-30 16:13:12 -08:00
+++ b/sound/pci/emu10k1/emu10k1.c 2005-03-30 16:13:12 -08:00
@@ -140,9 +140,11 @@
return err;
}
/* This stores the periods table. */
- if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024,
&emu->p16v_buffer) < 0) {
- snd_p16v_free(emu);
- return -ENOMEM;
+ if (emu->audigy && emu->revision == 4) { /* P16V */
+ if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
+ snd_p16v_free(emu);
+ return -ENOMEM;
+ }
}
if ((err = snd_emu10k1_mixer(emu)) < 0) {
diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c 2005-03-30 16:13:12 -08:00
+++ b/sound/pci/emu10k1/emu10k1_main.c 2005-03-30 16:13:12 -08:00
@@ -600,7 +600,8 @@
if (emu->port)
pci_release_regions(emu->pci);
pci_disable_device(emu->pci);
- snd_p16v_free(emu);
+ if (emu->audigy && emu->revision == 4) /* P16V */
+ snd_p16v_free(emu);
kfree(emu);
return 0;
}
diff -Nru a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
--- a/sound/pci/emu10k1/irq.c 2005-03-30 16:13:12 -08:00
+++ b/sound/pci/emu10k1/irq.c 2005-03-30 16:13:12 -08:00
@@ -170,19 +170,20 @@
}
outl(orig_status, emu->port + IPR); /* ack all */
}
- while ((status2 = inl(emu->port + IPR2)) != 0) {
- u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
- emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
- orig_status2 = status2;
- if(status2 & mask) {
- if(pvoice->use) {
- snd_pcm_period_elapsed(pvoice->epcm->substream);
- } else {
- snd_printk(KERN_ERR "p16v: status: 0x%08x,
mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
+ if (emu->audigy && emu->revision == 4) { /* P16V */
+ while ((status2 = inl(emu->port + IPR2)) != 0) {
+ u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
+ emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
+ orig_status2 = status2;
+ if(status2 & mask) {
+ if(pvoice->use) {
+
snd_pcm_period_elapsed(pvoice->epcm->substream);
+ } else {
+ snd_printk(KERN_ERR "p16v: status:
0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
+ }
}
+ outl(orig_status2, emu->port + IPR2); /* ack all */
}
- outl(orig_status2, emu->port + IPR2); /* ack all */
}
-
return IRQ_RETVAL(handled);
}
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html