aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-04-22 11:28:11 -0400
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:41 -0400
commitebf029da38829ede6b53ac8a5ad45b149064ea16 (patch)
treeaebf6bddd245a874577fc321978b3f7137e8ac39 /sound/pci/emu10k1
parent6b9a9b329640b7e8143df7b2782884ea758650f7 (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.c15
-rw-r--r--sound/pci/emu10k1/emu10k1x.c8
2 files changed, 12 insertions, 11 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 9a9b977d3cf1..abde5b901884 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)
1249 if (emu->port) { /* avoid access to already used hardware */ 1249 if (emu->port) { /* avoid access to already used hardware */
1250 snd_emu10k1_fx8010_tram_setup(emu, 0); 1250 snd_emu10k1_fx8010_tram_setup(emu, 0);
1251 snd_emu10k1_done(emu); 1251 snd_emu10k1_done(emu);
1252 /* remove reserved page */
1253 if (emu->reserved_page) {
1254 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
1255 emu->reserved_page = NULL;
1256 }
1257 snd_emu10k1_free_efx(emu); 1252 snd_emu10k1_free_efx(emu);
1258 } 1253 }
1259 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { 1254 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
@@ -1262,6 +1257,14 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1262 } 1257 }
1263 if (emu->emu1010.firmware_thread) 1258 if (emu->emu1010.firmware_thread)
1264 kthread_stop(emu->emu1010.firmware_thread); 1259 kthread_stop(emu->emu1010.firmware_thread);
1260 if (emu->irq >= 0)
1261 free_irq(emu->irq, emu);
1262 /* remove reserved page */
1263 if (emu->reserved_page) {
1264 snd_emu10k1_synth_free(emu,
1265 (struct snd_util_memblk *)emu->reserved_page);
1266 emu->reserved_page = NULL;
1267 }
1265 if (emu->memhdr) 1268 if (emu->memhdr)
1266 snd_util_memhdr_free(emu->memhdr); 1269 snd_util_memhdr_free(emu->memhdr);
1267 if (emu->silent_page.area) 1270 if (emu->silent_page.area)
@@ -1273,8 +1276,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1273#ifdef CONFIG_PM 1276#ifdef CONFIG_PM
1274 free_pm_buffer(emu); 1277 free_pm_buffer(emu);
1275#endif 1278#endif
1276 if (emu->irq >= 0)
1277 free_irq(emu->irq, emu);
1278 if (emu->port) 1279 if (emu->port)
1279 pci_release_regions(emu->pci); 1280 pci_release_regions(emu->pci);
1280 if (emu->card_capabilities->ca0151_chip) /* P16V */ 1281 if (emu->card_capabilities->ca0151_chip) /* P16V */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 341f34e19f3c..491a4a50f869 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)
754 // disable audio 754 // disable audio
755 outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); 755 outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
756 756
757 // release the i/o port 757 /* release the irq */
758 release_and_free_resource(chip->res_port);
759
760 // release the irq
761 if (chip->irq >= 0) 758 if (chip->irq >= 0)
762 free_irq(chip->irq, chip); 759 free_irq(chip->irq, chip);
763 760
761 // release the i/o port
762 release_and_free_resource(chip->res_port);
763
764 // release the DMA 764 // release the DMA
765 if (chip->dma_buffer.area) { 765 if (chip->dma_buffer.area) {
766 snd_dma_free_pages(&chip->dma_buffer); 766 snd_dma_free_pages(&chip->dma_buffer);