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

Reply via email to