diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-04-22 17:28:11 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-04-24 12:00:41 +0200 |
commit | ebf029da38829ede6b53ac8a5ad45b149064ea16 (patch) | |
tree | aebf6bddd245a874577fc321978b3f7137e8ac39 /sound/pci/emu10k1 | |
parent | 6b9a9b329640b7e8143df7b2782884ea758650f7 (diff) |
[ALSA] Fix possible races at free_irq in PCI drivers
The irq handler of PCI drivers must be released before releasing other
resources since the handler for a shared irq can be still called and
may access the freed resource again.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 15 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1x.c | 8 |
2 files changed, 12 insertions, 11 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 9a9b977d3cf..abde5b90188 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1249,11 +1249,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) if (emu->port) { /* avoid access to already used hardware */ snd_emu10k1_fx8010_tram_setup(emu, 0); snd_emu10k1_done(emu); - /* remove reserved page */ - if (emu->reserved_page) { - snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page); - emu->reserved_page = NULL; - } snd_emu10k1_free_efx(emu); } if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { @@ -1262,6 +1257,14 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) } if (emu->emu1010.firmware_thread) kthread_stop(emu->emu1010.firmware_thread); + if (emu->irq >= 0) + free_irq(emu->irq, emu); + /* remove reserved page */ + if (emu->reserved_page) { + snd_emu10k1_synth_free(emu, + (struct snd_util_memblk *)emu->reserved_page); + emu->reserved_page = NULL; + } if (emu->memhdr) snd_util_memhdr_free(emu->memhdr); if (emu->silent_page.area) @@ -1273,8 +1276,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) #ifdef CONFIG_PM free_pm_buffer(emu); #endif - if (emu->irq >= 0) - free_irq(emu->irq, emu); if (emu->port) pci_release_regions(emu->pci); if (emu->card_capabilities->ca0151_chip) /* P16V */ diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 341f34e19f3..491a4a50f86 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -754,13 +754,13 @@ static int snd_emu10k1x_free(struct emu10k1x *chip) // disable audio outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); - // release the i/o port - release_and_free_resource(chip->res_port); - - // release the irq + /* release the irq */ if (chip->irq >= 0) free_irq(chip->irq, chip); + // release the i/o port + release_and_free_resource(chip->res_port); + // release the DMA if (chip->dma_buffer.area) { snd_dma_free_pages(&chip->dma_buffer); |