diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-04-22 11:28:11 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-04-24 06:00:41 -0400 |
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 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); |