Commit 18e131d1 authored by Peter Wächtler's avatar Peter Wächtler Committed by Jeff Garzik

[PATCH] oss sound cli cleanup

More cleanups for the OSS sound modules
parent dd140c87
...@@ -826,37 +826,48 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -826,37 +826,48 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) && if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
(bits & PCM_ENABLE_OUTPUT)) (bits & PCM_ENABLE_OUTPUT))
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&dmap->lock,flags);
changed = audio_devs[dev]->enable_bits ^ bits; if (bits & PCM_ENABLE_INPUT)
if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go) {
spin_lock_irqsave(&dmap_in->lock,flags);
changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_INPUT;
if (changed && audio_devs[dev]->go)
{ {
reorganize_buffers(dev, dmap_in, 1); reorganize_buffers(dev, dmap_in, 1);
if ((err = audio_devs[dev]->d->prepare_for_input(dev, if ((err = audio_devs[dev]->d->prepare_for_input(dev,
dmap_in->fragment_size, dmap_in->nbufs)) < 0) { dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
spin_unlock_irqrestore(&dmap->lock,flags); spin_unlock_irqrestore(&dmap_in->lock,flags);
return -err; return -err;
} }
dmap_in->dma_mode = DMODE_INPUT; dmap_in->dma_mode = DMODE_INPUT;
audio_devs[dev]->enable_bits = bits; audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
DMAbuf_activate_recording(dev, dmap_in); DMAbuf_activate_recording(dev, dmap_in);
} else
audio_devs[dev]->enable_bits &= ~PCM_ENABLE_INPUT;
spin_unlock_irqrestore(&dmap_in->lock,flags);
} }
if ((changed & bits) & PCM_ENABLE_OUTPUT && if (bits & PCM_ENABLE_OUTPUT)
{
spin_lock_irqsave(&dmap_out->lock,flags);
changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_OUTPUT;
if (changed &&
(dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) && (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
audio_devs[dev]->go) audio_devs[dev]->go)
{ {
if (!(dmap_out->flags & DMA_ALLOC_DONE)) if (!(dmap_out->flags & DMA_ALLOC_DONE))
reorganize_buffers(dev, dmap_out, 0); reorganize_buffers(dev, dmap_out, 0);
dmap_out->dma_mode = DMODE_OUTPUT; dmap_out->dma_mode = DMODE_OUTPUT;
audio_devs[dev]->enable_bits = bits; audio_devs[dev]->enable_bits |= PCM_ENABLE_OUTPUT;
dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size; dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
DMAbuf_launch_output(dev, dmap_out); DMAbuf_launch_output(dev, dmap_out);
} else
audio_devs[dev]->enable_bits &= ~PCM_ENABLE_OUTPUT;
spin_unlock_irqrestore(&dmap_out->lock,flags);
} }
audio_devs[dev]->enable_bits = bits;
#if 0 #if 0
if (changed && audio_devs[dev]->d->trigger) if (changed && audio_devs[dev]->d->trigger)
audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go); audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
#endif #endif
spin_unlock_irqrestore(&dmap->lock,flags);
/* Falls through... */ /* Falls through... */
case SNDCTL_DSP_GETTRIGGER: case SNDCTL_DSP_GETTRIGGER:
...@@ -873,7 +884,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -873,7 +884,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
case SNDCTL_DSP_GETIPTR: case SNDCTL_DSP_GETIPTR:
if (!(audio_devs[dev]->open_mode & OPEN_READ)) if (!(audio_devs[dev]->open_mode & OPEN_READ))
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&dmap->lock,flags); spin_lock_irqsave(&dmap_in->lock,flags);
cinfo.bytes = dmap_in->byte_counter; cinfo.bytes = dmap_in->byte_counter;
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3; cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0) if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
...@@ -882,7 +893,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -882,7 +893,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
cinfo.bytes += cinfo.ptr; cinfo.bytes += cinfo.ptr;
if (dmap_in->mapping_flags & DMA_MAP_MAPPED) if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
dmap_in->qlen = 0; /* Reset interrupt counter */ dmap_in->qlen = 0; /* Reset interrupt counter */
spin_unlock_irqrestore(&dmap->lock,flags); spin_unlock_irqrestore(&dmap_in->lock,flags);
if (copy_to_user(arg, &cinfo, sizeof(cinfo))) if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -891,7 +902,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -891,7 +902,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&dmap->lock,flags); spin_lock_irqsave(&dmap_out->lock,flags);
cinfo.bytes = dmap_out->byte_counter; cinfo.bytes = dmap_out->byte_counter;
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3; cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0) if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
...@@ -900,7 +911,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -900,7 +911,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
cinfo.bytes += cinfo.ptr; cinfo.bytes += cinfo.ptr;
if (dmap_out->mapping_flags & DMA_MAP_MAPPED) if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
dmap_out->qlen = 0; /* Reset interrupt counter */ dmap_out->qlen = 0; /* Reset interrupt counter */
spin_unlock_irqrestore(&dmap->lock,flags); spin_unlock_irqrestore(&dmap_out->lock,flags);
if (copy_to_user(arg, &cinfo, sizeof(cinfo))) if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -913,7 +924,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -913,7 +924,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
ret=0; ret=0;
break; break;
} }
spin_lock_irqsave(&dmap->lock,flags); spin_lock_irqsave(&dmap_out->lock,flags);
/* Compute number of bytes that have been played */ /* Compute number of bytes that have been played */
count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT); count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
if (count < dmap_out->fragment_size && dmap_out->qhead != 0) if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
...@@ -923,7 +934,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -923,7 +934,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
count = dmap_out->user_counter - count; count = dmap_out->user_counter - count;
if (count < 0) if (count < 0)
count = 0; count = 0;
spin_unlock_irqrestore(&dmap->lock,flags); spin_unlock_irqrestore(&dmap_out->lock,flags);
ret = count; ret = count;
break; break;
......
...@@ -166,6 +166,7 @@ struct sound_settings { ...@@ -166,6 +166,7 @@ struct sound_settings {
int treble; int treble;
int gain; int gain;
int minDev; /* minor device number currently open */ int minDev; /* minor device number currently open */
spinlock_t lock;
}; };
extern struct sound_settings dmasound; extern struct sound_settings dmasound;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/soundcard.h> #include <linux/soundcard.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/spinlock.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/atariints.h> #include <asm/atariints.h>
...@@ -1262,7 +1262,7 @@ static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp) ...@@ -1262,7 +1262,7 @@ static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp)
return; return;
} }
#endif #endif
spin_lock(&dmasound.lock);
if (write_sq_ignore_int && is_falcon) { if (write_sq_ignore_int && is_falcon) {
/* ++TeSche: Falcon only: ignore first irq because it comes /* ++TeSche: Falcon only: ignore first irq because it comes
* immediately after starting a frame. after that, irqs come * immediately after starting a frame. after that, irqs come
...@@ -1314,6 +1314,7 @@ static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp) ...@@ -1314,6 +1314,7 @@ static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp)
/* We are not playing after AtaPlay(), so there /* We are not playing after AtaPlay(), so there
is nothing to play any more. Wake up a process is nothing to play any more. Wake up a process
waiting for audio output to drain. */ waiting for audio output to drain. */
spin_unlock(&dmasound.lock);
} }
...@@ -1349,14 +1350,15 @@ static void __init FalconMixerInit(void) ...@@ -1349,14 +1350,15 @@ static void __init FalconMixerInit(void)
static int AtaMixerIoctl(u_int cmd, u_long arg) static int AtaMixerIoctl(u_int cmd, u_long arg)
{ {
int data; int data;
unsigned long flags;
switch (cmd) { switch (cmd) {
case SOUND_MIXER_READ_SPEAKER: case SOUND_MIXER_READ_SPEAKER:
if (is_falcon || MACH_IS_TT) { if (is_falcon || MACH_IS_TT) {
int porta; int porta;
cli(); spin_lock_irqsave(&dmasound.lock, flags);
sound_ym.rd_data_reg_sel = 14; sound_ym.rd_data_reg_sel = 14;
porta = sound_ym.rd_data_reg_sel; porta = sound_ym.rd_data_reg_sel;
sti(); spin_unlock_irqrestore(&dmasound.lock, flags);
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100); return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
} }
break; break;
...@@ -1367,12 +1369,12 @@ static int AtaMixerIoctl(u_int cmd, u_long arg) ...@@ -1367,12 +1369,12 @@ static int AtaMixerIoctl(u_int cmd, u_long arg)
if (is_falcon || MACH_IS_TT) { if (is_falcon || MACH_IS_TT) {
int porta; int porta;
IOCTL_IN(arg, data); IOCTL_IN(arg, data);
cli(); spin_lock_irqsave(&dmasound.lock, flags);
sound_ym.rd_data_reg_sel = 14; sound_ym.rd_data_reg_sel = 14;
porta = (sound_ym.rd_data_reg_sel & ~0x40) | porta = (sound_ym.rd_data_reg_sel & ~0x40) |
(data < 50 ? 0x40 : 0); (data < 50 ? 0x40 : 0);
sound_ym.wd_data = porta; sound_ym.wd_data = porta;
sti(); spin_unlock_irqrestore(&dmasound.lock, flags);
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100); return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
} }
} }
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/vt_kern.h> #include <linux/vt_kern.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/spinlock.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#ifdef CONFIG_ADB_CUDA #ifdef CONFIG_ADB_CUDA
...@@ -397,6 +398,7 @@ read_audio_gpio(int gpio_addr) ...@@ -397,6 +398,7 @@ read_audio_gpio(int gpio_addr)
static void static void
headphone_intr(int irq, void *devid, struct pt_regs *regs) headphone_intr(int irq, void *devid, struct pt_regs *regs)
{ {
spin_lock(&dmasound.lock);
if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) { if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
printk(KERN_INFO "Audio jack plugged, muting speakers.\n"); printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
...@@ -406,6 +408,7 @@ headphone_intr(int irq, void *devid, struct pt_regs *regs) ...@@ -406,6 +408,7 @@ headphone_intr(int irq, void *devid, struct pt_regs *regs)
write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol); write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
} }
spin_unlock(&dmasound.lock);
} }
...@@ -804,7 +807,7 @@ static void __PMacPlay(void) ...@@ -804,7 +807,7 @@ static void __PMacPlay(void)
/* CHECK: how much of this *really* needs IRQs masked? */ /* CHECK: how much of this *really* needs IRQs masked? */
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
count = 300 ; /* > two cycles at the lowest sample rate */ count = 300 ; /* > two cycles at the lowest sample rate */
/* what we want to send next */ /* what we want to send next */
...@@ -871,7 +874,7 @@ static void __PMacPlay(void) ...@@ -871,7 +874,7 @@ static void __PMacPlay(void)
out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
++write_sq.active; ++write_sq.active;
} }
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
} }
static void PMacPlay(void) static void PMacPlay(void)
...@@ -889,14 +892,14 @@ static void PMacRecord(void) ...@@ -889,14 +892,14 @@ static void PMacRecord(void)
if (read_sq.active) if (read_sq.active)
return; return;
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
/* This is all we have to do......Just start it up. /* This is all we have to do......Just start it up.
*/ */
out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
read_sq.active = 1; read_sq.active = 1;
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
} }
/* if the TX status comes up "DEAD" - reported on some Power Computing machines /* if the TX status comes up "DEAD" - reported on some Power Computing machines
...@@ -929,6 +932,7 @@ pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs) ...@@ -929,6 +932,7 @@ pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs)
/* != 0 when we are dealing with a DEAD xfer */ /* != 0 when we are dealing with a DEAD xfer */
static int emergency_in_use = 0 ; static int emergency_in_use = 0 ;
spin_lock(&dmasound.lock);
while (write_sq.active > 0) { /* we expect to have done something*/ while (write_sq.active > 0) { /* we expect to have done something*/
if (emergency_in_use) /* we are dealing with DEAD xfer */ if (emergency_in_use) /* we are dealing with DEAD xfer */
cp = emergency_dbdma_cmd ; cp = emergency_dbdma_cmd ;
...@@ -1004,6 +1008,7 @@ printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ; ...@@ -1004,6 +1008,7 @@ printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
/* make the wake-on-empty conditional on syncing */ /* make the wake-on-empty conditional on syncing */
if (!write_sq.active && (write_sq.syncing & 1)) if (!write_sq.active && (write_sq.syncing & 1))
WAKE_UP(write_sq.sync_queue); /* any time we're empty */ WAKE_UP(write_sq.sync_queue); /* any time we're empty */
spin_unlock(&dmasound.lock);
} }
...@@ -1025,6 +1030,7 @@ pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs) ...@@ -1025,6 +1030,7 @@ pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs)
if (read_sq.active == 0) if (read_sq.active == 0)
return; return;
spin_lock(&dmasound.lock);
/* Check multiple buffers in case we were held off from /* Check multiple buffers in case we were held off from
* interrupt processing for a long time. Geeze, I really hope * interrupt processing for a long time. Geeze, I really hope
* this doesn't happen. * this doesn't happen.
...@@ -1056,6 +1062,7 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n"); ...@@ -1056,6 +1062,7 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
/* should complete clearing the DEAD status */ /* should complete clearing the DEAD status */
out_le32(&awacs_rxdma->control, out_le32(&awacs_rxdma->control,
((RUN|WAKE) << 16) + (RUN|WAKE)); ((RUN|WAKE) << 16) + (RUN|WAKE));
spin_unlock(&dmasound.lock);
return; /* try this block again */ return; /* try this block again */
} }
/* Clear status and move on to next buffer. /* Clear status and move on to next buffer.
...@@ -1083,13 +1090,16 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n"); ...@@ -1083,13 +1090,16 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
} }
WAKE_UP(read_sq.action_queue); WAKE_UP(read_sq.action_queue);
spin_unlock(&dmasound.lock);
} }
static void static void
pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs) pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
{ {
int ctrl = in_le32(&awacs->control); int ctrl;
spin_lock(&dmasound.lock);
ctrl = in_le32(&awacs->control);
if (ctrl & MASK_PORTCHG) { if (ctrl & MASK_PORTCHG) {
/* do something when headphone is plugged/unplugged? */ /* do something when headphone is plugged/unplugged? */
...@@ -1102,6 +1112,7 @@ pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs) ...@@ -1102,6 +1112,7 @@ pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
} }
/* Writing 1s to the CNTLERR and PORTCHG bits clears them... */ /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
out_le32(&awacs->control, ctrl); out_le32(&awacs->control, ctrl);
spin_unlock(&dmasound.lock);
} }
static void static void
...@@ -1125,7 +1136,7 @@ static void awacs_nosound(unsigned long xx) ...@@ -1125,7 +1136,7 @@ static void awacs_nosound(unsigned long xx)
unsigned long flags; unsigned long flags;
int count = 600 ; /* > four samples at lowest rate */ int count = 600 ; /* > four samples at lowest rate */
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
if (beep_playing) { if (beep_playing) {
st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
...@@ -1141,7 +1152,7 @@ static void awacs_nosound(unsigned long xx) ...@@ -1141,7 +1152,7 @@ static void awacs_nosound(unsigned long xx)
out_le32(&awacs->byteswap, 0); out_le32(&awacs->byteswap, 0);
beep_playing = 0; beep_playing = 0;
} }
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
} }
static struct timer_list beep_timer = { static struct timer_list beep_timer = {
...@@ -1189,19 +1200,19 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) ...@@ -1189,19 +1200,19 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
return; return;
#endif #endif
} }
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
del_timer(&beep_timer); del_timer(&beep_timer);
if (ticks) { if (ticks) {
beep_timer.expires = jiffies + ticks; beep_timer.expires = jiffies + ticks;
add_timer(&beep_timer); add_timer(&beep_timer);
} }
if (beep_playing || write_sq.active || beep_buf == NULL) { if (beep_playing || write_sq.active || beep_buf == NULL) {
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
return; /* too hard, sorry :-( */ return; /* too hard, sorry :-( */
} }
beep_playing = 1; beep_playing = 1;
st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS); st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
if (hz == beep_hz_cache && beep_vol == beep_volume_cache) { if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
nsamples = beep_nsamples_cache; nsamples = beep_nsamples_cache;
...@@ -1227,7 +1238,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) ...@@ -1227,7 +1238,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf)); st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
awacs_beep_state = 1; awacs_beep_state = 1;
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
if (beep_playing) { /* i.e. haven't been terminated already */ if (beep_playing) { /* i.e. haven't been terminated already */
int count = 300 ; int count = 300 ;
out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
...@@ -1242,7 +1253,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) ...@@ -1242,7 +1253,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
(void)in_le32(&awacs_txdma->status); (void)in_le32(&awacs_txdma->status);
out_le32(&awacs_txdma->control, RUN | (RUN << 16)); out_le32(&awacs_txdma->control, RUN | (RUN << 16));
} }
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
} }
/* used in init and for wake-up */ /* used in init and for wake-up */
...@@ -1430,7 +1441,7 @@ awacs_burgundy_rcw(unsigned addr) ...@@ -1430,7 +1441,7 @@ awacs_burgundy_rcw(unsigned addr)
unsigned long flags; unsigned long flags;
/* should have timeouts here */ /* should have timeouts here */
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
out_le32(&awacs->codec_ctrl, addr + 0x100000); out_le32(&awacs->codec_ctrl, addr + 0x100000);
awacs_burgundy_busy_wait(); awacs_burgundy_busy_wait();
...@@ -1452,7 +1463,7 @@ awacs_burgundy_rcw(unsigned addr) ...@@ -1452,7 +1463,7 @@ awacs_burgundy_rcw(unsigned addr)
awacs_burgundy_extend_wait(); awacs_burgundy_extend_wait();
val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24; val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
return val; return val;
} }
...@@ -1472,14 +1483,14 @@ awacs_burgundy_rcb(unsigned addr) ...@@ -1472,14 +1483,14 @@ awacs_burgundy_rcb(unsigned addr)
unsigned long flags; unsigned long flags;
/* should have timeouts here */ /* should have timeouts here */
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
out_le32(&awacs->codec_ctrl, addr + 0x100000); out_le32(&awacs->codec_ctrl, addr + 0x100000);
awacs_burgundy_busy_wait(); awacs_burgundy_busy_wait();
awacs_burgundy_extend_wait(); awacs_burgundy_extend_wait();
val += (in_le32(&awacs->codec_stat) >> 4) & 0xff; val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
restore_flags(flags); spin_unlock_irqrestore(&dmasound.lock, flags);
return val; return val;
} }
......
...@@ -597,9 +597,9 @@ static ssize_t sq_write(struct file *file, const char *src, size_t uLeft, ...@@ -597,9 +597,9 @@ static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
is drained - and if we get here in time then it does not apply. is drained - and if we get here in time then it does not apply.
*/ */
save_flags(flags) ; cli() ; spin_lock_irqsave(&dmasound.lock, flags);
write_sq.syncing &= ~2 ; /* take out POST status */ write_sq.syncing &= ~2 ; /* take out POST status */
restore_flags(flags) ; spin_unlock_irqrestore(&dmasound.lock, flags);
if (write_sq.count > 0 && if (write_sq.count > 0 &&
(bLeft = write_sq.block_size-write_sq.rear_size) > 0) { (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
...@@ -1347,6 +1347,7 @@ static int __init sq_init(void) ...@@ -1347,6 +1347,7 @@ static int __init sq_init(void)
if (dmasound.mach.record) if (dmasound.mach.record)
sq_fops.read = sq_read ; sq_fops.read = sq_read ;
#endif #endif
spin_lock_init(&dmasound.lock);
sq_unit = register_sound_dsp(&sq_fops, -1); sq_unit = register_sound_dsp(&sq_fops, -1);
if (sq_unit < 0) { if (sq_unit < 0) {
printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
......
...@@ -459,28 +459,32 @@ static void Q40Play(void) ...@@ -459,28 +459,32 @@ static void Q40Play(void)
*/ */
return; return;
} }
save_flags(flags); cli(); spin_lock_irqsave(&dmasound.lock, flags);
Q40PlayNextFrame(1); Q40PlayNextFrame(1);
restore_flags(flags); spin_unlock_irqrestore_flags(&dmasound.lock, flags);
} }
static void Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp) static void Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp)
{ {
spin_lock(&dmasound.lock);
if (q40_sc>1){ if (q40_sc>1){
*DAC_LEFT=*q40_pp++; *DAC_LEFT=*q40_pp++;
*DAC_RIGHT=*q40_pp++; *DAC_RIGHT=*q40_pp++;
q40_sc -=2; q40_sc -=2;
master_outb(1,SAMPLE_CLEAR_REG); master_outb(1,SAMPLE_CLEAR_REG);
}else Q40Interrupt(); }else Q40Interrupt();
spin_unlock(&dmasound.lock);
} }
static void Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp) static void Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp)
{ {
spin_lock(&dmasound.lock);
if (q40_sc>0){ if (q40_sc>0){
*DAC_LEFT=*q40_pp; *DAC_LEFT=*q40_pp;
*DAC_RIGHT=*q40_pp++; *DAC_RIGHT=*q40_pp++;
q40_sc --; q40_sc --;
master_outb(1,SAMPLE_CLEAR_REG); master_outb(1,SAMPLE_CLEAR_REG);
}else Q40Interrupt(); }else Q40Interrupt();
spin_unlock(&dmasound.lock);
} }
static void Q40Interrupt(void) static void Q40Interrupt(void)
{ {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "gus.h" #include "gus.h"
...@@ -25,7 +26,7 @@ static int midi_busy = 0, input_opened = 0; ...@@ -25,7 +26,7 @@ static int midi_busy = 0, input_opened = 0;
static int my_dev; static int my_dev;
static int output_used = 0; static int output_used = 0;
static volatile unsigned char gus_midi_control; static volatile unsigned char gus_midi_control;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
static void (*midi_input_intr) (int dev, unsigned char data); static void (*midi_input_intr) (int dev, unsigned char data);
static unsigned char tmp_queue[256]; static unsigned char tmp_queue[256];
...@@ -75,8 +76,7 @@ static int dump_to_midi(unsigned char midi_byte) ...@@ -75,8 +76,7 @@ static int dump_to_midi(unsigned char midi_byte)
output_used = 1; output_used = 1;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY) if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
{ {
...@@ -92,7 +92,7 @@ static int dump_to_midi(unsigned char midi_byte) ...@@ -92,7 +92,7 @@ static int dump_to_midi(unsigned char midi_byte)
outb((gus_midi_control), u_MidiControl); outb((gus_midi_control), u_MidiControl);
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return ok; return ok;
} }
...@@ -113,16 +113,14 @@ static int gus_midi_out(int dev, unsigned char midi_byte) ...@@ -113,16 +113,14 @@ static int gus_midi_out(int dev, unsigned char midi_byte)
/* /*
* Drain the local queue first * Drain the local queue first
*/ */
spin_lock_irqsave(&lock, flags);
save_flags(flags);
cli();
while (qlen && dump_to_midi(tmp_queue[qhead])) while (qlen && dump_to_midi(tmp_queue[qhead]))
{ {
qlen--; qlen--;
qhead++; qhead++;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
/* /*
* Output the byte if the local queue is empty. * Output the byte if the local queue is empty.
...@@ -142,14 +140,13 @@ static int gus_midi_out(int dev, unsigned char midi_byte) ...@@ -142,14 +140,13 @@ static int gus_midi_out(int dev, unsigned char midi_byte)
return 0; /* return 0; /*
* Local queue full * Local queue full
*/ */
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
tmp_queue[qtail] = midi_byte; tmp_queue[qtail] = midi_byte;
qlen++; qlen++;
qtail++; qtail++;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 1; return 1;
} }
...@@ -174,15 +171,14 @@ static int gus_midi_buffer_status(int dev) ...@@ -174,15 +171,14 @@ static int gus_midi_buffer_status(int dev)
if (!output_used) if (!output_used)
return 0; return 0;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (qlen && dump_to_midi(tmp_queue[qhead])) if (qlen && dump_to_midi(tmp_queue[qhead]))
{ {
qlen--; qlen--;
qhead++; qhead++;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY); return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
} }
...@@ -226,11 +222,9 @@ void __init gus_midi_init(struct address_info *hw_config) ...@@ -226,11 +222,9 @@ void __init gus_midi_init(struct address_info *hw_config)
void gus_midi_interrupt(int dummy) void gus_midi_interrupt(int dummy)
{ {
volatile unsigned char stat, data; volatile unsigned char stat, data;
unsigned long flags;
int timeout = 10; int timeout = 10;
save_flags(flags); spin_lock(&lock);
cli();
while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY)) while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
{ {
...@@ -258,5 +252,5 @@ void gus_midi_interrupt(int dummy) ...@@ -258,5 +252,5 @@ void gus_midi_interrupt(int dummy)
} }
} }
} }
restore_flags(flags); spin_unlock(&lock);
} }
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/spinlock.h>
#define GUSPNP_AUTODETECT #define GUSPNP_AUTODETECT
...@@ -138,6 +139,7 @@ static int pcm_current_block; ...@@ -138,6 +139,7 @@ static int pcm_current_block;
static unsigned long pcm_current_buf; static unsigned long pcm_current_buf;
static int pcm_current_count; static int pcm_current_count;
static int pcm_current_intrflag; static int pcm_current_intrflag;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
extern int *gus_osp; extern int *gus_osp;
...@@ -226,8 +228,6 @@ static void gus_poke(long addr, unsigned char data) ...@@ -226,8 +228,6 @@ static void gus_poke(long addr, unsigned char data)
{ /* Writes a byte to the DRAM */ { /* Writes a byte to the DRAM */
unsigned long flags; unsigned long flags;
save_flags(flags);
cli();
outb((0x43), u_Command); outb((0x43), u_Command);
outb((addr & 0xff), u_DataLo); outb((addr & 0xff), u_DataLo);
outb(((addr >> 8) & 0xff), u_DataHi); outb(((addr >> 8) & 0xff), u_DataHi);
...@@ -235,16 +235,12 @@ static void gus_poke(long addr, unsigned char data) ...@@ -235,16 +235,12 @@ static void gus_poke(long addr, unsigned char data)
outb((0x44), u_Command); outb((0x44), u_Command);
outb(((addr >> 16) & 0xff), u_DataHi); outb(((addr >> 16) & 0xff), u_DataHi);
outb((data), u_DRAMIO); outb((data), u_DRAMIO);
restore_flags(flags);
} }
static unsigned char gus_peek(long addr) static unsigned char gus_peek(long addr)
{ /* Reads a byte from the DRAM */ { /* Reads a byte from the DRAM */
unsigned long flags;
unsigned char tmp; unsigned char tmp;
save_flags(flags);
cli();
outb((0x43), u_Command); outb((0x43), u_Command);
outb((addr & 0xff), u_DataLo); outb((addr & 0xff), u_DataLo);
outb(((addr >> 8) & 0xff), u_DataHi); outb(((addr >> 8) & 0xff), u_DataHi);
...@@ -252,35 +248,23 @@ static unsigned char gus_peek(long addr) ...@@ -252,35 +248,23 @@ static unsigned char gus_peek(long addr)
outb((0x44), u_Command); outb((0x44), u_Command);
outb(((addr >> 16) & 0xff), u_DataHi); outb(((addr >> 16) & 0xff), u_DataHi);
tmp = inb(u_DRAMIO); tmp = inb(u_DRAMIO);
restore_flags(flags);
return tmp; return tmp;
} }
void gus_write8(int reg, unsigned int data) void gus_write8(int reg, unsigned int data)
{ /* Writes to an indirect register (8 bit) */ { /* Writes to an indirect register (8 bit) */
unsigned long flags;
save_flags(flags);
cli();
outb((reg), u_Command); outb((reg), u_Command);
outb(((unsigned char) (data & 0xff)), u_DataHi); outb(((unsigned char) (data & 0xff)), u_DataHi);
restore_flags(flags);
} }
static unsigned char gus_read8(int reg) static unsigned char gus_read8(int reg)
{ {
/* Reads from an indirect register (8 bit). Offset 0x80. */ /* Reads from an indirect register (8 bit). Offset 0x80. */
unsigned long flags;
unsigned char val; unsigned char val;
save_flags(flags);
cli();
outb((reg | 0x80), u_Command); outb((reg | 0x80), u_Command);
val = inb(u_DataHi); val = inb(u_DataHi);
restore_flags(flags);
return val; return val;
} }
...@@ -288,14 +272,10 @@ static unsigned char gus_read8(int reg) ...@@ -288,14 +272,10 @@ static unsigned char gus_read8(int reg)
static unsigned char gus_look8(int reg) static unsigned char gus_look8(int reg)
{ {
/* Reads from an indirect register (8 bit). No additional offset. */ /* Reads from an indirect register (8 bit). No additional offset. */
unsigned long flags;
unsigned char val; unsigned char val;
save_flags(flags);
cli();
outb((reg), u_Command); outb((reg), u_Command);
val = inb(u_DataHi); val = inb(u_DataHi);
restore_flags(flags);
return val; return val;
} }
...@@ -303,54 +283,35 @@ static unsigned char gus_look8(int reg) ...@@ -303,54 +283,35 @@ static unsigned char gus_look8(int reg)
static void gus_write16(int reg, unsigned int data) static void gus_write16(int reg, unsigned int data)
{ {
/* Writes to an indirect register (16 bit) */ /* Writes to an indirect register (16 bit) */
unsigned long flags;
save_flags(flags);
cli();
outb((reg), u_Command); outb((reg), u_Command);
outb(((unsigned char) (data & 0xff)), u_DataLo); outb(((unsigned char) (data & 0xff)), u_DataLo);
outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi); outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi);
restore_flags(flags);
} }
static unsigned short gus_read16(int reg) static unsigned short gus_read16(int reg)
{ {
/* Reads from an indirect register (16 bit). Offset 0x80. */ /* Reads from an indirect register (16 bit). Offset 0x80. */
unsigned long flags;
unsigned char hi, lo; unsigned char hi, lo;
save_flags(flags);
cli();
outb((reg | 0x80), u_Command); outb((reg | 0x80), u_Command);
lo = inb(u_DataLo); lo = inb(u_DataLo);
hi = inb(u_DataHi); hi = inb(u_DataHi);
restore_flags(flags);
return ((hi << 8) & 0xff00) | lo; return ((hi << 8) & 0xff00) | lo;
} }
static unsigned short gus_look16(int reg) static unsigned short gus_look16(int reg)
{ {
/* Reads from an indirect register (16 bit). No additional offset. */ /* Reads from an indirect register (16 bit). No additional offset. */
unsigned long flags;
unsigned char hi, lo; unsigned char hi, lo;
save_flags(flags);
cli();
outb((reg), u_Command); outb((reg), u_Command);
lo = inb(u_DataLo); lo = inb(u_DataLo);
hi = inb(u_DataHi); hi = inb(u_DataHi);
restore_flags(flags);
return ((hi << 8) & 0xff00) | lo; return ((hi << 8) & 0xff00) | lo;
} }
...@@ -358,10 +319,7 @@ static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit ...@@ -358,10 +319,7 @@ static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit
{ {
/* Writes an 24 bit memory address */ /* Writes an 24 bit memory address */
unsigned long hold_address; unsigned long hold_address;
unsigned long flags;
save_flags(flags);
cli();
if (is16bit) if (is16bit)
{ {
if (iw_mode) if (iw_mode)
...@@ -389,7 +347,6 @@ static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit ...@@ -389,7 +347,6 @@ static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit
gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff)); gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff) gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
+ (frac << 5)); + (frac << 5));
restore_flags(flags);
} }
static void gus_select_voice(int voice) static void gus_select_voice(int voice)
...@@ -514,8 +471,7 @@ static void gus_voice_init(int voice) ...@@ -514,8 +471,7 @@ static void gus_voice_init(int voice)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_volume(0); gus_voice_volume(0);
gus_voice_off(); gus_voice_off();
...@@ -524,7 +480,7 @@ static void gus_voice_init(int voice) ...@@ -524,7 +480,7 @@ static void gus_voice_init(int voice)
gus_write8(0x0d, 0x03); /* Ramping off */ gus_write8(0x0d, 0x03); /* Ramping off */
voice_alloc->map[voice] = 0; voice_alloc->map[voice] = 0;
voice_alloc->alloc_times[voice] = 0; voice_alloc->alloc_times[voice] = 0;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
...@@ -558,11 +514,10 @@ static void step_envelope(int voice) ...@@ -558,11 +514,10 @@ static void step_envelope(int voice)
if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2) if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
{ {
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_rampoff(); gus_rampoff();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
/* /*
* Sustain phase begins. Continue envelope after receiving note off. * Sustain phase begins. Continue envelope after receiving note off.
...@@ -580,8 +535,7 @@ static void step_envelope(int voice) ...@@ -580,8 +535,7 @@ static void step_envelope(int voice)
vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255; vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
rate = voices[voice].env_rate[phase]; rate = voices[voice].env_rate[phase];
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_volume(prev_vol); gus_voice_volume(prev_vol);
...@@ -593,7 +547,7 @@ static void step_envelope(int voice) ...@@ -593,7 +547,7 @@ static void step_envelope(int voice)
if (((vol - prev_vol) / 64) == 0) /* No significant volume change */ if (((vol - prev_vol) / 64) == 0) /* No significant volume change */
{ {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
step_envelope(voice); /* Continue the envelope on the next step */ step_envelope(voice); /* Continue the envelope on the next step */
return; return;
} }
...@@ -612,7 +566,7 @@ static void step_envelope(int voice) ...@@ -612,7 +566,7 @@ static void step_envelope(int voice)
gus_rampon(0x60); /* Decreasing volume, with IRQ */ gus_rampon(0x60); /* Decreasing volume, with IRQ */
} }
voices[voice].current_volume = vol; voices[voice].current_volume = vol;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void init_envelope(int voice) static void init_envelope(int voice)
...@@ -623,7 +577,7 @@ static void init_envelope(int voice) ...@@ -623,7 +577,7 @@ static void init_envelope(int voice)
step_envelope(voice); step_envelope(voice);
} }
static void start_release(int voice, long int flags) static void start_release(int voice)
{ {
if (gus_read8(0x00) & 0x03) if (gus_read8(0x00) & 0x03)
return; /* Voice already stopped */ return; /* Voice already stopped */
...@@ -635,7 +589,6 @@ static void start_release(int voice, long int flags) ...@@ -635,7 +589,6 @@ static void start_release(int voice, long int flags)
voices[voice].mode &= ~WAVE_SUSTAIN_ON; voices[voice].mode &= ~WAVE_SUSTAIN_ON;
gus_rampoff(); gus_rampoff();
restore_flags(flags);
step_envelope(voice); step_envelope(voice);
} }
...@@ -644,23 +597,22 @@ static void gus_voice_fade(int voice) ...@@ -644,23 +597,22 @@ static void gus_voice_fade(int voice)
int instr_no = sample_map[voice], is16bits; int instr_no = sample_map[voice], is16bits;
long int flags; long int flags;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
if (instr_no < 0 || instr_no > MAX_SAMPLE) if (instr_no < 0 || instr_no > MAX_SAMPLE)
{ {
gus_write8(0x00, 0x03); /* Hard stop */ gus_write8(0x00, 0x03); /* Hard stop */
voice_alloc->map[voice] = 0; voice_alloc->map[voice] = 0;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
} }
is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */ is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
{ {
start_release(voice, flags); start_release(voice);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
} }
/* /*
...@@ -671,14 +623,14 @@ static void gus_voice_fade(int voice) ...@@ -671,14 +623,14 @@ static void gus_voice_fade(int voice)
gus_voice_off(); gus_voice_off();
gus_rampoff(); gus_rampoff();
gus_voice_init(voice); gus_voice_init(voice);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
} }
gus_ramp_range(65, 4030); gus_ramp_range(65, 4030);
gus_ramp_rate(2, 4); gus_ramp_rate(2, 4);
gus_rampon(0x40 | 0x20); /* Down, once, with IRQ */ gus_rampon(0x40 | 0x20); /* Down, once, with IRQ */
voices[voice].volume_irq_mode = VMODE_HALT; voices[voice].volume_irq_mode = VMODE_HALT;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void gus_reset(void) static void gus_reset(void)
...@@ -710,8 +662,7 @@ static void gus_initialize(void) ...@@ -710,8 +662,7 @@ static void gus_initialize(void)
0, 1, 0, 2, 0, 3, 4, 5 0, 1, 0, 2, 0, 3, 4, 5
}; };
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_write8(0x4c, 0); /* Reset GF1 */ gus_write8(0x4c, 0); /* Reset GF1 */
gus_delay(); gus_delay();
gus_delay(); gus_delay();
...@@ -850,7 +801,7 @@ static void gus_initialize(void) ...@@ -850,7 +801,7 @@ static void gus_initialize(void)
if (iw_mode) if (iw_mode)
gus_write8(0x19, gus_read8(0x19) | 0x01); gus_write8(0x19, gus_read8(0x19) | 0x01);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
...@@ -1159,17 +1110,16 @@ static int guswave_kill_note(int dev, int voice, int note, int velocity) ...@@ -1159,17 +1110,16 @@ static int guswave_kill_note(int dev, int voice, int note, int velocity)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
/* voice_alloc->map[voice] = 0xffff; */ /* voice_alloc->map[voice] = 0xffff; */
if (voices[voice].volume_irq_mode == VMODE_START_NOTE) if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
{ {
voices[voice].kill_pending = 1; voices[voice].kill_pending = 1;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
else else
{ {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
gus_voice_fade(voice); gus_voice_fade(voice);
} }
...@@ -1227,8 +1177,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time) ...@@ -1227,8 +1177,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time)
compute_volume(voice, volume); compute_volume(voice, volume);
voices[voice].current_volume = voices[voice].initial_volume; voices[voice].current_volume = voices[voice].initial_volume;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
/* /*
* CAUTION! Interrupts disabled. Enable them before returning * CAUTION! Interrupts disabled. Enable them before returning
*/ */
...@@ -1242,7 +1191,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time) ...@@ -1242,7 +1191,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time)
{ {
gus_rampoff(); gus_rampoff();
gus_voice_volume(target); gus_voice_volume(target);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
} }
if (ramp_time == FAST_RAMP) if (ramp_time == FAST_RAMP)
...@@ -1255,7 +1204,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time) ...@@ -1255,7 +1204,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time)
{ {
gus_rampoff(); gus_rampoff();
gus_voice_volume(target); gus_voice_volume(target);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return; return;
} }
if (target > curr) if (target > curr)
...@@ -1273,7 +1222,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time) ...@@ -1273,7 +1222,7 @@ static void compute_and_set_volume(int voice, int volume, int ramp_time)
gus_ramp_range(target, curr); gus_ramp_range(target, curr);
gus_rampon(0x40); /* Ramp down, once, no irq */ gus_rampon(0x40); /* Ramp down, once, no irq */
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void dynamic_volume_change(int voice) static void dynamic_volume_change(int voice)
...@@ -1281,11 +1230,10 @@ static void dynamic_volume_change(int voice) ...@@ -1281,11 +1230,10 @@ static void dynamic_volume_change(int voice)
unsigned char status; unsigned char status;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
status = gus_read8(0x00); /* Get voice status */ status = gus_read8(0x00); /* Get voice status */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (status & 0x03) if (status & 0x03)
return; /* Voice was not running */ return; /* Voice was not running */
...@@ -1300,11 +1248,10 @@ static void dynamic_volume_change(int voice) ...@@ -1300,11 +1248,10 @@ static void dynamic_volume_change(int voice)
* Voice is running and has envelopes. * Voice is running and has envelopes.
*/ */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
status = gus_read8(0x0d); /* Ramping status */ status = gus_read8(0x0d); /* Ramping status */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (status & 0x03) /* Sustain phase? */ if (status & 0x03) /* Sustain phase? */
{ {
...@@ -1336,11 +1283,10 @@ static void guswave_controller(int dev, int voice, int ctrl_num, int value) ...@@ -1336,11 +1283,10 @@ static void guswave_controller(int dev, int voice, int ctrl_num, int value)
freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0); freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
voices[voice].current_freq = freq; voices[voice].current_freq = freq;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_freq(freq); gus_voice_freq(freq);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
break; break;
...@@ -1497,17 +1443,12 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume) ...@@ -1497,17 +1443,12 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume)
((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE)) ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
printk(KERN_ERR "GUS: Sample address error\n"); printk(KERN_ERR "GUS: Sample address error\n");
} }
/************************************************************************* spin_lock_irqsave(&lock,flags);
* CAUTION! Interrupts disabled. Don't return before enabling
*************************************************************************/
save_flags(flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_off(); gus_voice_off();
gus_rampoff(); gus_rampoff();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
{ {
...@@ -1519,8 +1460,7 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume) ...@@ -1519,8 +1460,7 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume)
compute_and_set_volume(voice, volume, 0); compute_and_set_volume(voice, volume, 0);
} }
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
if (samples[sample].mode & WAVE_LOOP_BACK) if (samples[sample].mode & WAVE_LOOP_BACK)
...@@ -1560,7 +1500,7 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume) ...@@ -1560,7 +1500,7 @@ static int guswave_start_note2(int dev, int voice, int note_num, int volume)
gus_voice_freq(freq); gus_voice_freq(freq);
gus_voice_balance(pan); gus_voice_balance(pan);
gus_voice_on(mode); gus_voice_on(mode);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
} }
...@@ -1577,8 +1517,7 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume) ...@@ -1577,8 +1517,7 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume)
int mode; int mode;
int ret_val = 0; int ret_val = 0;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
if (note_num == 255) if (note_num == 255)
{ {
if (voices[voice].volume_irq_mode == VMODE_START_NOTE) if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
...@@ -1604,11 +1543,10 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume) ...@@ -1604,11 +1543,10 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume)
if (voices[voice].sample_pending >= 0) if (voices[voice].sample_pending >= 0)
{ {
restore_flags(flags); /* Run temporarily with interrupts enabled */ spin_unlock_irqrestore(&lock,flags); /* Run temporarily with interrupts enabled */
guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending); guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
voices[voice].sample_pending = -1; voices[voice].sample_pending = -1;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); /* Reselect the voice (just to be sure) */ gus_select_voice(voice); /* Reselect the voice (just to be sure) */
} }
if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065)) if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
...@@ -1628,7 +1566,7 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume) ...@@ -1628,7 +1566,7 @@ static int guswave_start_note(int dev, int voice, int note_num, int volume)
gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */ gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return ret_val; return ret_val;
} }
...@@ -1871,9 +1809,7 @@ static int guswave_load_patch(int dev, int format, const char *addr, ...@@ -1871,9 +1809,7 @@ static int guswave_load_patch(int dev, int format, const char *addr,
blk_sz)) blk_sz))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
/******** INTERRUPTS DISABLED NOW ********/
gus_write8(0x41, 0); /* Disable GF1 DMA */ gus_write8(0x41, 0); /* Disable GF1 DMA */
DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys, DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
blk_sz, DMA_MODE_WRITE); blk_sz, DMA_MODE_WRITE);
...@@ -1924,16 +1860,15 @@ static int guswave_load_patch(int dev, int format, const char *addr, ...@@ -1924,16 +1860,15 @@ static int guswave_load_patch(int dev, int format, const char *addr,
if (audio_devs[gus_devnum]->dmap_out->dma > 3) if (audio_devs[gus_devnum]->dmap_out->dma > 3)
dma_command |= 0x04; /* 16 bit DMA _channel_ */ dma_command |= 0x04; /* 16 bit DMA _channel_ */
gus_write8(0x41, dma_command); /* Lets go luteet (=bugs) */
/* /*
* Sleep here until the DRAM DMA done interrupt is served * Sleep here until the DRAM DMA done interrupt is served
*/ */
active_device = GUS_DEV_WAVE; active_device = GUS_DEV_WAVE;
gus_write8(0x41, dma_command); /* Lets go luteet (=bugs) */
spin_unlock_irqrestore(&lock,flags); /* opens a race */
if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ)) if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ))
printk("GUS: DMA Transfer timed out\n"); printk("GUS: DMA Transfer timed out\n");
restore_flags(flags);
} }
/* /*
...@@ -1972,11 +1907,10 @@ static void guswave_hw_control(int dev, unsigned char *event_rec) ...@@ -1972,11 +1907,10 @@ static void guswave_hw_control(int dev, unsigned char *event_rec)
switch (cmd) switch (cmd)
{ {
case _GUS_NUMVOICES: case _GUS_NUMVOICES:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_select_max_voices(p1); gus_select_max_voices(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICESAMPLE: case _GUS_VOICESAMPLE:
...@@ -1984,20 +1918,18 @@ static void guswave_hw_control(int dev, unsigned char *event_rec) ...@@ -1984,20 +1918,18 @@ static void guswave_hw_control(int dev, unsigned char *event_rec)
break; break;
case _GUS_VOICEON: case _GUS_VOICEON:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
p1 &= ~0x20; /* Don't allow interrupts */ p1 &= ~0x20; /* Don't allow interrupts */
gus_voice_on(p1); gus_voice_on(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEOFF: case _GUS_VOICEOFF:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_off(); gus_voice_off();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEFADE: case _GUS_VOICEFADE:
...@@ -2005,36 +1937,32 @@ static void guswave_hw_control(int dev, unsigned char *event_rec) ...@@ -2005,36 +1937,32 @@ static void guswave_hw_control(int dev, unsigned char *event_rec)
break; break;
case _GUS_VOICEMODE: case _GUS_VOICEMODE:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
p1 &= ~0x20; /* Don't allow interrupts */ p1 &= ~0x20; /* Don't allow interrupts */
gus_voice_mode(p1); gus_voice_mode(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEBALA: case _GUS_VOICEBALA:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_balance(p1); gus_voice_balance(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEFREQ: case _GUS_VOICEFREQ:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_freq(plong); gus_voice_freq(plong);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEVOL: case _GUS_VOICEVOL:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_volume(p1); gus_voice_volume(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOICEVOL2: /* Just update the software voice level */ case _GUS_VOICEVOL2: /* Just update the software voice level */
...@@ -2044,53 +1972,48 @@ static void guswave_hw_control(int dev, unsigned char *event_rec) ...@@ -2044,53 +1972,48 @@ static void guswave_hw_control(int dev, unsigned char *event_rec)
case _GUS_RAMPRANGE: case _GUS_RAMPRANGE:
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
break; /* NO-NO */ break; /* NO-NO */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_ramp_range(p1, p2); gus_ramp_range(p1, p2);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_RAMPRATE: case _GUS_RAMPRATE:
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
break; /* NJET-NJET */ break; /* NJET-NJET */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_ramp_rate(p1, p2); gus_ramp_rate(p1, p2);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_RAMPMODE: case _GUS_RAMPMODE:
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
break; /* NO-NO */ break; /* NO-NO */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
p1 &= ~0x20; /* Don't allow interrupts */ p1 &= ~0x20; /* Don't allow interrupts */
gus_ramp_mode(p1); gus_ramp_mode(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_RAMPON: case _GUS_RAMPON:
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
break; /* EI-EI */ break; /* EI-EI */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
p1 &= ~0x20; /* Don't allow interrupts */ p1 &= ~0x20; /* Don't allow interrupts */
gus_rampon(p1); gus_rampon(p1);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_RAMPOFF: case _GUS_RAMPOFF:
if (voices[voice].mode & WAVE_ENVELOPES) if (voices[voice].mode & WAVE_ENVELOPES)
break; /* NEJ-NEJ */ break; /* NEJ-NEJ */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_rampoff(); gus_rampoff();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
case _GUS_VOLUME_SCALE: case _GUS_VOLUME_SCALE:
...@@ -2099,11 +2022,10 @@ static void guswave_hw_control(int dev, unsigned char *event_rec) ...@@ -2099,11 +2022,10 @@ static void guswave_hw_control(int dev, unsigned char *event_rec)
break; break;
case _GUS_VOICE_POS: case _GUS_VOICE_POS:
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_set_voice_pos(voice, plong); gus_set_voice_pos(voice, plong);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
break; break;
default: default:
...@@ -2294,13 +2216,12 @@ static void gus_audio_update_volume(void) ...@@ -2294,13 +2216,12 @@ static void gus_audio_update_volume(void)
if (pcm_active && pcm_opened) if (pcm_active && pcm_opened)
for (voice = 0; voice < gus_audio_channels; voice++) for (voice = 0; voice < gus_audio_channels; voice++)
{ {
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_rampoff(); gus_rampoff();
gus_voice_volume(1530 + (25 * gus_pcm_volume)); gus_voice_volume(1530 + (25 * gus_pcm_volume));
gus_ramp_range(65, 1530 + (25 * gus_pcm_volume)); gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
} }
...@@ -2348,8 +2269,7 @@ static void play_next_pcm_block(void) ...@@ -2348,8 +2269,7 @@ static void play_next_pcm_block(void)
if (chn == 0) if (chn == 0)
ramp_mode[chn] = 0x04; /* Enable rollover bit */ ramp_mode[chn] = 0x04; /* Enable rollover bit */
} }
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(chn); gus_select_voice(chn);
gus_voice_freq(speed); gus_voice_freq(speed);
...@@ -2386,18 +2306,17 @@ static void play_next_pcm_block(void) ...@@ -2386,18 +2306,17 @@ static void play_next_pcm_block(void)
0, is16bits); /* Loop end location */ 0, is16bits); /* Loop end location */
else else
mode[chn] |= 0x08; /* Enable looping */ mode[chn] |= 0x08; /* Enable looping */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
for (chn = 0; chn < gus_audio_channels; chn++) for (chn = 0; chn < gus_audio_channels; chn++)
{ {
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(chn); gus_select_voice(chn);
gus_write8(0x0d, ramp_mode[chn]); gus_write8(0x0d, ramp_mode[chn]);
if (iw_mode) if (iw_mode)
gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */ gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */
gus_voice_on(mode[chn]); gus_voice_on(mode[chn]);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
pcm_active = 1; pcm_active = 1;
} }
...@@ -2419,8 +2338,7 @@ static void gus_transfer_output_block(int dev, unsigned long buf, ...@@ -2419,8 +2338,7 @@ static void gus_transfer_output_block(int dev, unsigned long buf,
unsigned char dma_command; unsigned char dma_command;
unsigned long address, hold_address; unsigned long address, hold_address;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
count = total_count / gus_audio_channels; count = total_count / gus_audio_channels;
...@@ -2485,7 +2403,7 @@ static void gus_transfer_output_block(int dev, unsigned long buf, ...@@ -2485,7 +2403,7 @@ static void gus_transfer_output_block(int dev, unsigned long buf,
active_device = GUS_DEV_PCM_CONTINUE; active_device = GUS_DEV_PCM_CONTINUE;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void gus_uninterleave8(char *buf, int l) static void gus_uninterleave8(char *buf, int l)
...@@ -2547,8 +2465,7 @@ static void gus_audio_start_input(int dev, unsigned long buf, int count, ...@@ -2547,8 +2465,7 @@ static void gus_audio_start_input(int dev, unsigned long buf, int count,
unsigned long flags; unsigned long flags;
unsigned char mode; unsigned char mode;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ); DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
mode = 0xa0; /* DMA IRQ enabled, invert MSB */ mode = 0xa0; /* DMA IRQ enabled, invert MSB */
...@@ -2560,7 +2477,7 @@ static void gus_audio_start_input(int dev, unsigned long buf, int count, ...@@ -2560,7 +2477,7 @@ static void gus_audio_start_input(int dev, unsigned long buf, int count,
mode |= 0x01; /* DMA enable */ mode |= 0x01; /* DMA enable */
gus_write8(0x49, mode); gus_write8(0x49, mode);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static int gus_audio_prepare_for_input(int dev, int bsize, int bcount) static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
...@@ -2656,11 +2573,10 @@ static void guswave_bender(int dev, int voice, int value) ...@@ -2656,11 +2573,10 @@ static void guswave_bender(int dev, int voice, int value)
freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0); freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
voices[voice].current_freq = freq; voices[voice].current_freq = freq;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
gus_voice_freq(freq); gus_voice_freq(freq);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc) static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
...@@ -2741,8 +2657,7 @@ static void set_input_volumes(void) ...@@ -2741,8 +2657,7 @@ static void set_input_volumes(void)
if (have_gus_max) /* Don't disturb GUS MAX */ if (have_gus_max) /* Don't disturb GUS MAX */
return; return;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
/* /*
* Enable channels having vol > 10% * Enable channels having vol > 10%
...@@ -2768,7 +2683,7 @@ static void set_input_volumes(void) ...@@ -2768,7 +2683,7 @@ static void set_input_volumes(void)
mix_image |= mask & 0x07; mix_image |= mask & 0x07;
outb((mix_image), u_Mixer); outb((mix_image), u_Mixer);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
...@@ -2977,11 +2892,10 @@ void __init gus_wave_init(struct address_info *hw_config) ...@@ -2977,11 +2892,10 @@ void __init gus_wave_init(struct address_info *hw_config)
* Versions < 3.6 don't have the digital ASIC. Try to probe it first. * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
*/ */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
outb((0x20), gus_base + 0x0f); outb((0x20), gus_base + 0x0f);
val = inb(gus_base + 0x0f); val = inb(gus_base + 0x0f);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (gus_pnp_flag || (val != 0xff && (val & 0x06))) /* Should be 0x02?? */ if (gus_pnp_flag || (val != 0xff && (val & 0x06))) /* Should be 0x02?? */
{ {
...@@ -3206,15 +3120,13 @@ void __exit gus_wave_unload(struct address_info *hw_config) ...@@ -3206,15 +3120,13 @@ void __exit gus_wave_unload(struct address_info *hw_config)
vfree(samples); vfree(samples);
samples=NULL; samples=NULL;
} }
/* called in interrupt context */
static void do_loop_irq(int voice) static void do_loop_irq(int voice)
{ {
unsigned char tmp; unsigned char tmp;
int mode, parm; int mode, parm;
unsigned long flags;
save_flags(flags); spin_lock(&lock);
cli();
gus_select_voice(voice); gus_select_voice(voice);
tmp = gus_read8(0x00); tmp = gus_read8(0x00);
...@@ -3290,7 +3202,7 @@ static void do_loop_irq(int voice) ...@@ -3290,7 +3202,7 @@ static void do_loop_irq(int voice)
default: default:
break; break;
} }
restore_flags(flags); spin_unlock(&lock);
} }
static void do_volume_irq(int voice) static void do_volume_irq(int voice)
...@@ -3299,8 +3211,7 @@ static void do_volume_irq(int voice) ...@@ -3299,8 +3211,7 @@ static void do_volume_irq(int voice)
int mode, parm; int mode, parm;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
gus_select_voice(voice); gus_select_voice(voice);
tmp = gus_read8(0x0d); tmp = gus_read8(0x0d);
...@@ -3318,18 +3229,18 @@ static void do_volume_irq(int voice) ...@@ -3318,18 +3229,18 @@ static void do_volume_irq(int voice)
case VMODE_HALT: /* Decay phase finished */ case VMODE_HALT: /* Decay phase finished */
if (iw_mode) if (iw_mode)
gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */ gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
gus_voice_init(voice); gus_voice_init(voice);
break; break;
case VMODE_ENVELOPE: case VMODE_ENVELOPE:
gus_rampoff(); gus_rampoff();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
step_envelope(voice); step_envelope(voice);
break; break;
case VMODE_START_NOTE: case VMODE_START_NOTE:
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
guswave_start_note2(voices[voice].dev_pending, voice, guswave_start_note2(voices[voice].dev_pending, voice,
voices[voice].note_pending, voices[voice].volume_pending); voices[voice].note_pending, voices[voice].volume_pending);
if (voices[voice].kill_pending) if (voices[voice].kill_pending)
...@@ -3345,11 +3256,10 @@ static void do_volume_irq(int voice) ...@@ -3345,11 +3256,10 @@ static void do_volume_irq(int voice)
break; break;
default: default:
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
restore_flags(flags);
} }
/* called in irq context */
void gus_voice_irq(void) void gus_voice_irq(void)
{ {
unsigned long wave_ignore = 0, volume_ignore = 0; unsigned long wave_ignore = 0, volume_ignore = 0;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init() * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init()
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include <linux/ultrasound.h> #include <linux/ultrasound.h>
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
extern int *gus_osp; extern int *gus_osp;
extern int gus_base; extern int gus_base;
extern spinlock_t lock;
static int volumes[ICS_MIXDEVS]; static int volumes[ICS_MIXDEVS];
static int left_fix[ICS_MIXDEVS] = static int left_fix[ICS_MIXDEVS] =
{1, 1, 1, 2, 1, 2}; {1, 1, 1, 2, 1, 2};
...@@ -85,13 +87,12 @@ static void write_mix(int dev, int chn, int vol) ...@@ -85,13 +87,12 @@ static void write_mix(int dev, int chn, int vol)
attn_addr |= 0x03; attn_addr |= 0x03;
} }
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
outb((ctrl_addr), u_MixSelect); outb((ctrl_addr), u_MixSelect);
outb((selector[dev]), u_MixData); outb((selector[dev]), u_MixData);
outb((attn_addr), u_MixSelect); outb((attn_addr), u_MixSelect);
outb(((unsigned char) vol), u_MixData); outb(((unsigned char) vol), u_MixData);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static int set_volumes(int dev, int vol) static int set_volumes(int dev, int vol)
......
...@@ -3,7 +3,7 @@ typedef struct vmidi_devc { ...@@ -3,7 +3,7 @@ typedef struct vmidi_devc {
/* State variables */ /* State variables */
int opened; int opened;
spinlock_t lock;
/* MIDI fields */ /* MIDI fields */
int my_mididev; int my_mididev;
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include <linux/wavefront.h> #include <linux/wavefront.h>
...@@ -79,6 +80,7 @@ static struct wf_mpu_config *phys_dev = &devs[0]; ...@@ -79,6 +80,7 @@ static struct wf_mpu_config *phys_dev = &devs[0];
static struct wf_mpu_config *virt_dev = &devs[1]; static struct wf_mpu_config *virt_dev = &devs[1];
static void start_uart_mode (void); static void start_uart_mode (void);
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
#define OUTPUT_READY 0x40 #define OUTPUT_READY 0x40
#define INPUT_AVAIL 0x80 #define INPUT_AVAIL 0x80
...@@ -365,8 +367,8 @@ wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy) ...@@ -365,8 +367,8 @@ wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
} }
if (mi->m_busy) return; if (mi->m_busy) return;
spin_lock(&lock);
mi->m_busy = 1; mi->m_busy = 1;
sti ();
if (!input_dev) { if (!input_dev) {
input_dev = physical_dev; input_dev = physical_dev;
...@@ -406,6 +408,7 @@ wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy) ...@@ -406,6 +408,7 @@ wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
} while (input_avail() && n-- > 0); } while (input_avail() && n-- > 0);
mi->m_busy = 0; mi->m_busy = 0;
spin_unlock(&lock);
} }
static int static int
...@@ -486,18 +489,17 @@ wf_mpu_out (int dev, unsigned char midi_byte) ...@@ -486,18 +489,17 @@ wf_mpu_out (int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready (); for (timeout = 30000; timeout > 0 && !output_ready ();
timeout--); timeout--);
save_flags (flags); spin_lock_irqsave(&lock,flags);
cli ();
if (!output_ready ()) { if (!output_ready ()) {
printk (KERN_WARNING "WF-MPU: Send switch " printk (KERN_WARNING "WF-MPU: Send switch "
"byte timeout\n"); "byte timeout\n");
restore_flags (flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
} }
write_data (switchch); write_data (switchch);
restore_flags (flags); spin_unlock_irqrestore(&lock,flags);
} }
lastoutdev = dev; lastoutdev = dev;
...@@ -511,16 +513,15 @@ wf_mpu_out (int dev, unsigned char midi_byte) ...@@ -511,16 +513,15 @@ wf_mpu_out (int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready (); timeout--); for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
save_flags (flags); spin_lock_irqsave(&lock,flags);
cli ();
if (!output_ready ()) { if (!output_ready ()) {
spin_unlock_irqrestore(&lock,flags);
printk (KERN_WARNING "WF-MPU: Send data timeout\n"); printk (KERN_WARNING "WF-MPU: Send data timeout\n");
restore_flags (flags);
return 0; return 0;
} }
write_data (midi_byte); write_data (midi_byte);
restore_flags (flags); spin_unlock_irqrestore(&lock,flags);
return 1; return 1;
} }
...@@ -768,14 +769,13 @@ virtual_midi_disable (void) ...@@ -768,14 +769,13 @@ virtual_midi_disable (void)
{ {
unsigned long flags; unsigned long flags;
save_flags (flags); spin_lock_irqsave(&lock,flags);
cli();
wf_mpu_close (virt_dev->devno); wf_mpu_close (virt_dev->devno);
/* no synth on virt_dev, so no need to call wf_mpu_synth_close() */ /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
phys_dev->isvirtual = 0; phys_dev->isvirtual = 0;
restore_flags (flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
} }
...@@ -858,8 +858,7 @@ start_uart_mode (void) ...@@ -858,8 +858,7 @@ start_uart_mode (void)
int ok, i; int ok, i;
unsigned long flags; unsigned long flags;
save_flags (flags); spin_lock_irqsave(&lock,flags);
cli ();
/* XXX fix me */ /* XXX fix me */
...@@ -875,6 +874,6 @@ start_uart_mode (void) ...@@ -875,6 +874,6 @@ start_uart_mode (void)
} }
} }
restore_flags (flags); spin_unlock_irqrestore(&lock,flags);
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment