diff options
author | Jaroslav Kysela <perex@suse.cz> | 2005-01-03 16:17:36 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-01-03 16:17:36 +0100 |
commit | 53f740539cd816e04690b332624f4413e35b1cef (patch) | |
tree | 62dca0ef47b409d4249161af1e8e10104f39618c /sound | |
parent | 469fb049ff5b775153d600811928d0a44215edb5 (diff) | |
download | history-53f740539cd816e04690b332624f4413e35b1cef.tar.gz |
[ALSA] Fix spinlock
au88x0 driver
Fixed possible spin deadlocks.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/au88x0/au88x0_core.c | 8 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0_pcm.c | 9 |
2 files changed, 15 insertions, 2 deletions
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index b7b17bbb5478c9..772bc612465031 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -2108,7 +2108,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2))) return -EBUSY; - spin_lock(&vortex->lock); if (dma >= 0) { en = 0; vortex_adb_checkinout(vortex, @@ -2304,7 +2303,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) } } vortex->dma_adb[dma].nr_ch = nr_ch; - spin_unlock(&vortex->lock); #if 0 /* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */ @@ -2433,22 +2431,28 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (source & IRQ_PCMOUT) { /* ALSA period acknowledge. */ + spin_lock(&vortex->lock); for (i = 0; i < NR_ADB; i++) { if (vortex->dma_adb[i].fifo_status == FIFO_START) { if (vortex_adbdma_bufshift(vortex, i)) ; + spin_unlock(&vortex->lock); snd_pcm_period_elapsed(vortex->dma_adb[i]. substream); + spin_lock(&vortex->lock); } } #ifndef CHIP_AU8810 for (i = 0; i < NR_WT; i++) { if (vortex->dma_wt[i].fifo_status == FIFO_START) { if (vortex_wtdma_bufshift(vortex, i)) ; + spin_unlock(&vortex->lock); snd_pcm_period_elapsed(vortex->dma_wt[i]. substream); + spin_lock(&vortex->lock); } } #endif + spin_unlock(&vortex->lock); handled = 1; } //Acknowledge the Timer interrupt diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index c9dfc32cc3ea05..066e6c698a7217 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -206,6 +206,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), params_period_bytes(hw_params), params_channels(hw_params)); */ + spin_lock_irq(&chip->lock); // Make audio routes and config buffer DMA. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { int dma, type = VORTEX_PCM_TYPE(substream->pcm); @@ -243,6 +244,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, params_periods(hw_params)); } #endif + spin_unlock_irq(&chip->lock); return 0; } @@ -252,6 +254,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream) vortex_t *chip = snd_pcm_substream_chip(substream); stream_t *stream = (stream_t *) (substream->runtime->private_data); + spin_lock_irq(&chip->lock); // Delete audio routes. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { if (stream != NULL) @@ -266,6 +269,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream) } #endif substream->runtime->private_data = NULL; + spin_unlock_irq(&chip->lock); return snd_pcm_lib_free_pages(substream); } @@ -284,6 +288,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream) else dir = 0; fmt = vortex_alsafmt_aspfmt(runtime->format); + spin_lock_irq(&chip->lock); if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ , 0); @@ -298,6 +303,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream) vortex_wtdma_setstartbuffer(chip, dma, 0); } #endif + spin_unlock_irq(&chip->lock); return 0; } @@ -308,6 +314,7 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd) stream_t *stream = (stream_t *) substream->runtime->private_data; int dma = stream->dma; + spin_lock(&chip->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: // do something to start the PCM engine @@ -357,8 +364,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd) #endif break; default: + spin_unlock(&chip->lock); return -EINVAL; } + spin_unlock(&chip->lock); return 0; } |