Commit 8afa2c8f authored by Linus Torvalds's avatar Linus Torvalds

Merge penguin:v2.5/linux

into home.transmeta.com:/home/torvalds/v2.5/linux
parents f3a88067 2b6ad47a
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/isapnp.h> #include <linux/isapnp.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#define DEBUGNOISE(x) #define DEBUGNOISE(x)
...@@ -77,7 +77,7 @@ typedef struct ...@@ -77,7 +77,7 @@ typedef struct
in ad1816_info */ in ad1816_info */
int irq_ok; int irq_ok;
int *osp; int *osp;
spinlock_t lock;
} ad1816_info; } ad1816_info;
static int nr_ad1816_devs; static int nr_ad1816_devs;
...@@ -109,12 +109,11 @@ static int ad_read (ad1816_info * devc, int reg) ...@@ -109,12 +109,11 @@ static int ad_read (ad1816_info * devc, int reg)
CHECK_FOR_POWER; CHECK_FOR_POWER;
save_flags (flags); /* make register access atomic */ spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
cli ();
outb ((unsigned char) (reg & 0x3f), devc->base+0); outb ((unsigned char) (reg & 0x3f), devc->base+0);
result = inb(devc->base+2); result = inb(devc->base+2);
result+= inb(devc->base+3)<<8; result+= inb(devc->base+3)<<8;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
return (result); return (result);
} }
...@@ -126,12 +125,11 @@ static void ad_write (ad1816_info * devc, int reg, int data) ...@@ -126,12 +125,11 @@ static void ad_write (ad1816_info * devc, int reg, int data)
CHECK_FOR_POWER; CHECK_FOR_POWER;
save_flags (flags); /* make register access atomic */ spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
cli ();
outb ((unsigned char) (reg & 0xff), devc->base+0); outb ((unsigned char) (reg & 0xff), devc->base+0);
outb ((unsigned char) (data & 0xff),devc->base+2); outb ((unsigned char) (data & 0xff),devc->base+2);
outb ((unsigned char) ((data>>8)&0xff),devc->base+3); outb ((unsigned char) ((data>>8)&0xff),devc->base+3);
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
...@@ -147,8 +145,7 @@ static void ad1816_halt_input (int dev) ...@@ -147,8 +145,7 @@ static void ad1816_halt_input (int dev)
DEBUGINFO (printk("ad1816: halt_input called\n")); DEBUGINFO (printk("ad1816: halt_input called\n"));
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
if(!isa_dma_bridge_buggy) { if(!isa_dma_bridge_buggy) {
disable_dma(audio_devs[dev]->dmap_in->dma); disable_dma(audio_devs[dev]->dmap_in->dma);
...@@ -168,7 +165,7 @@ static void ad1816_halt_input (int dev) ...@@ -168,7 +165,7 @@ static void ad1816_halt_input (int dev)
outb (~0x40, devc->base+1); outb (~0x40, devc->base+1);
devc->audio_mode &= ~PCM_ENABLE_INPUT; devc->audio_mode &= ~PCM_ENABLE_INPUT;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static void ad1816_halt_output (int dev) static void ad1816_halt_output (int dev)
...@@ -180,8 +177,7 @@ static void ad1816_halt_output (int dev) ...@@ -180,8 +177,7 @@ static void ad1816_halt_output (int dev)
DEBUGINFO (printk("ad1816: halt_output called!\n")); DEBUGINFO (printk("ad1816: halt_output called!\n"));
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
/* Mute pcm output */ /* Mute pcm output */
ad_write(devc, 4, ad_read(devc,4)|0x8080); ad_write(devc, 4, ad_read(devc,4)|0x8080);
...@@ -203,7 +199,7 @@ static void ad1816_halt_output (int dev) ...@@ -203,7 +199,7 @@ static void ad1816_halt_output (int dev)
outb ((unsigned char)~0x80, devc->base+1); outb ((unsigned char)~0x80, devc->base+1);
devc->audio_mode &= ~PCM_ENABLE_OUTPUT; devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static void ad1816_output_block (int dev, unsigned long buf, static void ad1816_output_block (int dev, unsigned long buf,
...@@ -217,14 +213,13 @@ static void ad1816_output_block (int dev, unsigned long buf, ...@@ -217,14 +213,13 @@ static void ad1816_output_block (int dev, unsigned long buf,
cnt = count/4 - 1; cnt = count/4 - 1;
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
/* set transfer count */ /* set transfer count */
ad_write (devc, 8, cnt & 0xffff); ad_write (devc, 8, cnt & 0xffff);
devc->audio_mode |= PCM_ENABLE_OUTPUT; devc->audio_mode |= PCM_ENABLE_OUTPUT;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
...@@ -239,14 +234,13 @@ static void ad1816_start_input (int dev, unsigned long buf, int count, ...@@ -239,14 +234,13 @@ static void ad1816_start_input (int dev, unsigned long buf, int count,
cnt = count/4 - 1; cnt = count/4 - 1;
save_flags (flags); /* make register access atomic */ spin_lock_irqsave(&devc->lock,flags);
cli ();
/* set transfer count */ /* set transfer count */
ad_write (devc, 10, cnt & 0xffff); ad_write (devc, 10, cnt & 0xffff);
devc->audio_mode |= PCM_ENABLE_INPUT; devc->audio_mode |= PCM_ENABLE_INPUT;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static int ad1816_prepare_for_input (int dev, int bsize, int bcount) static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
...@@ -258,8 +252,7 @@ static int ad1816_prepare_for_input (int dev, int bsize, int bcount) ...@@ -258,8 +252,7 @@ static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
DEBUGINFO (printk ("ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount)); DEBUGINFO (printk ("ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
fmt_bits= (devc->format_bits&0x7)<<3; fmt_bits= (devc->format_bits&0x7)<<3;
...@@ -290,7 +283,7 @@ static int ad1816_prepare_for_input (int dev, int bsize, int bcount) ...@@ -290,7 +283,7 @@ static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
ad_write (devc, 2, freq & 0xffff); ad_write (devc, 2, freq & 0xffff);
ad_write (devc, 3, freq & 0xffff); ad_write (devc, 3, freq & 0xffff);
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_input(dev); ad1816_halt_input(dev);
return 0; return 0;
...@@ -305,8 +298,7 @@ static int ad1816_prepare_for_output (int dev, int bsize, int bcount) ...@@ -305,8 +298,7 @@ static int ad1816_prepare_for_output (int dev, int bsize, int bcount)
DEBUGINFO (printk ("ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount)); DEBUGINFO (printk ("ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
save_flags (flags); /* make register access atomic */ spin_lock_irqsave(&devc->lock,flags);
cli ();
fmt_bits= (devc->format_bits&0x7)<<3; fmt_bits= (devc->format_bits&0x7)<<3;
/* set mono/stereo mode */ /* set mono/stereo mode */
...@@ -335,7 +327,7 @@ static int ad1816_prepare_for_output (int dev, int bsize, int bcount) ...@@ -335,7 +327,7 @@ static int ad1816_prepare_for_output (int dev, int bsize, int bcount)
ad_write (devc, 2, freq & 0xffff); ad_write (devc, 2, freq & 0xffff);
ad_write (devc, 3, freq & 0xffff); ad_write (devc, 3, freq & 0xffff);
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_output(dev); ad1816_halt_output(dev);
return 0; return 0;
...@@ -351,8 +343,7 @@ static void ad1816_trigger (int dev, int state) ...@@ -351,8 +343,7 @@ static void ad1816_trigger (int dev, int state)
/* mode may have changed */ /* mode may have changed */
save_flags (flags); /* make register access atomic */ spin_lock_irqsave(&devc->lock,flags);
cli ();
/* mask out modes not specified on open call */ /* mask out modes not specified on open call */
state &= devc->audio_mode; state &= devc->audio_mode;
...@@ -377,7 +368,7 @@ static void ad1816_trigger (int dev, int state) ...@@ -377,7 +368,7 @@ static void ad1816_trigger (int dev, int state)
/* disable capture */ /* disable capture */
outb(inb(devc->base+8)&~0x01, devc->base+8); outb(inb(devc->base+8)&~0x01, devc->base+8);
} }
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
...@@ -480,11 +471,10 @@ static int ad1816_open (int dev, int mode) ...@@ -480,11 +471,10 @@ static int ad1816_open (int dev, int mode)
devc = (ad1816_info *) audio_devs[dev]->devc; devc = (ad1816_info *) audio_devs[dev]->devc;
/* make check if device already open atomic */ /* make check if device already open atomic */
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
if (devc->opened) { if (devc->opened) {
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
return -(EBUSY); return -(EBUSY);
} }
...@@ -497,7 +487,7 @@ static int ad1816_open (int dev, int mode) ...@@ -497,7 +487,7 @@ static int ad1816_open (int dev, int mode)
devc->channels=1; devc->channels=1;
ad1816_reset(devc->dev_no); /* halt all pending output */ ad1816_reset(devc->dev_no); /* halt all pending output */
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
return 0; return 0;
} }
...@@ -506,8 +496,7 @@ static void ad1816_close (int dev) /* close device */ ...@@ -506,8 +496,7 @@ static void ad1816_close (int dev) /* close device */
unsigned long flags; unsigned long flags;
ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc; ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
/* halt all pending output */ /* halt all pending output */
ad1816_reset(devc->dev_no); ad1816_reset(devc->dev_no);
...@@ -518,8 +507,7 @@ static void ad1816_close (int dev) /* close device */ ...@@ -518,8 +507,7 @@ static void ad1816_close (int dev) /* close device */
devc->audio_format=AFMT_U8; devc->audio_format=AFMT_U8;
devc->format_bits = 0; devc->format_bits = 0;
spin_unlock_irqrestore(&devc->lock,flags);
restore_flags (flags);
} }
...@@ -556,7 +544,6 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) ...@@ -556,7 +544,6 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
unsigned char status; unsigned char status;
ad1816_info *devc; ad1816_info *devc;
int dev; int dev;
unsigned long flags;
if (irq < 0 || irq > 15) { if (irq < 0 || irq > 15) {
...@@ -574,8 +561,7 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) ...@@ -574,8 +561,7 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
devc = (ad1816_info *) audio_devs[dev]->devc; devc = (ad1816_info *) audio_devs[dev]->devc;
save_flags(flags); spin_lock(&devc->lock);
cli();
/* read interrupt register */ /* read interrupt register */
status = inb (devc->base+1); status = inb (devc->base+1);
...@@ -595,7 +581,7 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) ...@@ -595,7 +581,7 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128)) if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128))
DMAbuf_outputintr (dev, 1); DMAbuf_outputintr (dev, 1);
restore_flags(flags); spin_unlock(&devc->lock);
} }
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
...@@ -1033,6 +1019,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) ...@@ -1033,6 +1019,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config )
devc->irq = 0; devc->irq = 0;
devc->opened = 0; devc->opened = 0;
devc->osp = osp; devc->osp = osp;
spin_lock_init(&devc->lock);
/* base+0: bit 1 must be set but not 255 */ /* base+0: bit 1 must be set but not 255 */
tmp=inb(devc->base); tmp=inb(devc->base);
......
This diff is collapsed.
...@@ -291,10 +291,6 @@ int audio_write(int dev, struct file *file, const char *buf, int count) ...@@ -291,10 +291,6 @@ int audio_write(int dev, struct file *file, const char *buf, int count)
if (audio_devs[dev]->local_conversion & CNV_MU_LAW) if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
{ {
/*
* This just allows interrupts while the conversion is running
*/
sti();
translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l); translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
} }
c -= used; c -= used;
...@@ -352,11 +348,6 @@ int audio_read(int dev, struct file *file, char *buf, int count) ...@@ -352,11 +348,6 @@ int audio_read(int dev, struct file *file, char *buf, int count)
if (audio_devs[dev]->local_conversion & CNV_MU_LAW) if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
{ {
/*
* This just allows interrupts while the conversion is running
*/
sti();
translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l); translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
} }
...@@ -515,8 +506,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg) ...@@ -515,8 +506,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
break; break;
} }
save_flags (flags); spin_lock_irqsave(&dmap->lock,flags);
cli();
/* Compute number of bytes that have been played */ /* Compute number of bytes that have been played */
count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT); count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
if (count < dmap->fragment_size && dmap->qhead != 0) if (count < dmap->fragment_size && dmap->qhead != 0)
...@@ -527,7 +517,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg) ...@@ -527,7 +517,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
count = dmap->user_counter - count; count = dmap->user_counter - count;
if (count < 0) if (count < 0)
count = 0; count = 0;
restore_flags (flags); spin_unlock_irqrestore(&dmap->lock,flags);
val = count; val = count;
break; break;
...@@ -836,15 +826,14 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -836,15 +826,14 @@ 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;
save_flags(flags); spin_lock_irqsave(&dmap->lock,flags);
cli();
changed = audio_devs[dev]->enable_bits ^ bits; changed = audio_devs[dev]->enable_bits ^ bits;
if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go) if ((changed & bits) & PCM_ENABLE_INPUT && 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) {
restore_flags(flags); spin_unlock_irqrestore(&dmap->lock,flags);
return -err; return -err;
} }
dmap_in->dma_mode = DMODE_INPUT; dmap_in->dma_mode = DMODE_INPUT;
...@@ -867,7 +856,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -867,7 +856,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
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
restore_flags(flags); spin_unlock_irqrestore(&dmap->lock,flags);
/* Falls through... */ /* Falls through... */
case SNDCTL_DSP_GETTRIGGER: case SNDCTL_DSP_GETTRIGGER:
...@@ -884,8 +873,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -884,8 +873,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;
save_flags(flags); spin_lock_irqsave(&dmap->lock,flags);
cli();
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)
...@@ -894,7 +882,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -894,7 +882,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 */
restore_flags(flags); spin_unlock_irqrestore(&dmap->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;
...@@ -903,8 +891,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -903,8 +891,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;
save_flags(flags); spin_lock_irqsave(&dmap->lock,flags);
cli();
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)
...@@ -913,7 +900,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -913,7 +900,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 */
restore_flags(flags); spin_unlock_irqrestore(&dmap->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;
...@@ -926,8 +913,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -926,8 +913,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
ret=0; ret=0;
break; break;
} }
save_flags(flags); spin_lock_irqsave(&dmap->lock,flags);
cli();
/* 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)
...@@ -937,7 +923,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg) ...@@ -937,7 +923,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;
restore_flags (flags); spin_unlock_irqrestore(&dmap->lock,flags);
ret = count; ret = count;
break; break;
......
This diff is collapsed.
This diff is collapsed.
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/spinlock.h>
#define MIDIBUF_C #define MIDIBUF_C
#include "sound_config.h" #include "sound_config.h"
...@@ -55,6 +55,7 @@ static struct timer_list poll_timer = { ...@@ -55,6 +55,7 @@ static struct timer_list poll_timer = {
}; };
static volatile int open_devs = 0; static volatile int open_devs = 0;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
#define DATA_AVAIL(q) (q->len) #define DATA_AVAIL(q) (q->len)
#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len) #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
...@@ -63,20 +64,20 @@ static volatile int open_devs = 0; ...@@ -63,20 +64,20 @@ static volatile int open_devs = 0;
if (SPACE_AVAIL(q)) \ if (SPACE_AVAIL(q)) \
{ \ { \
unsigned long flags; \ unsigned long flags; \
save_flags( flags);cli(); \ spin_lock_irqsave(&lock, flags); \
q->queue[q->tail] = (data); \ q->queue[q->tail] = (data); \
q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \ q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
restore_flags(flags); \ spin_unlock_irqrestore(&lock, flags); \
} }
#define REMOVE_BYTE(q, data) \ #define REMOVE_BYTE(q, data) \
if (DATA_AVAIL(q)) \ if (DATA_AVAIL(q)) \
{ \ { \
unsigned long flags; \ unsigned long flags; \
save_flags( flags);cli(); \ spin_lock_irqsave(&lock, flags); \
data = q->queue[q->head]; \ data = q->queue[q->head]; \
q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \ q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
restore_flags(flags); \ spin_unlock_irqrestore(&lock, flags); \
} }
static void drain_midi_queue(int dev) static void drain_midi_queue(int dev)
...@@ -122,8 +123,7 @@ static void midi_poll(unsigned long dummy) ...@@ -122,8 +123,7 @@ static void midi_poll(unsigned long dummy)
unsigned long flags; unsigned long flags;
int dev; int dev;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (open_devs) if (open_devs)
{ {
for (dev = 0; dev < num_midis; dev++) for (dev = 0; dev < num_midis; dev++)
...@@ -135,9 +135,9 @@ static void midi_poll(unsigned long dummy) ...@@ -135,9 +135,9 @@ static void midi_poll(unsigned long dummy)
{ {
int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head]; int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
restore_flags(flags); /* Give some time to others */ spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
ok = midi_devs[dev]->outputc(dev, c); ok = midi_devs[dev]->outputc(dev, c);
cli(); spin_lock_irqsave(&lock, flags);
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE; midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
midi_out_buf[dev]->len--; midi_out_buf[dev]->len--;
} }
...@@ -151,7 +151,7 @@ static void midi_poll(unsigned long dummy) ...@@ -151,7 +151,7 @@ static void midi_poll(unsigned long dummy)
* Come back later * Come back later
*/ */
} }
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
} }
int MIDIbuf_open(int dev, struct file *file) int MIDIbuf_open(int dev, struct file *file)
...@@ -217,7 +217,6 @@ int MIDIbuf_open(int dev, struct file *file) ...@@ -217,7 +217,6 @@ int MIDIbuf_open(int dev, struct file *file)
void MIDIbuf_release(int dev, struct file *file) void MIDIbuf_release(int dev, struct file *file)
{ {
int mode; int mode;
unsigned long flags;
dev = dev >> 4; dev = dev >> 4;
mode = translate_mode(file); mode = translate_mode(file);
...@@ -225,9 +224,6 @@ void MIDIbuf_release(int dev, struct file *file) ...@@ -225,9 +224,6 @@ void MIDIbuf_release(int dev, struct file *file)
if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL) if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
return; return;
save_flags(flags);
cli();
/* /*
* Wait until the queue is empty * Wait until the queue is empty
*/ */
...@@ -249,7 +245,6 @@ void MIDIbuf_release(int dev, struct file *file) ...@@ -249,7 +245,6 @@ void MIDIbuf_release(int dev, struct file *file)
* Ensure the output queues are empty * Ensure the output queues are empty
*/ */
} }
restore_flags(flags);
midi_devs[dev]->close(dev); midi_devs[dev]->close(dev);
...@@ -267,7 +262,6 @@ void MIDIbuf_release(int dev, struct file *file) ...@@ -267,7 +262,6 @@ void MIDIbuf_release(int dev, struct file *file)
int MIDIbuf_write(int dev, struct file *file, const char *buf, int count) int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
{ {
unsigned long flags;
int c, n, i; int c, n, i;
unsigned char tmp_data; unsigned char tmp_data;
...@@ -276,9 +270,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count) ...@@ -276,9 +270,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
if (!count) if (!count)
return 0; return 0;
save_flags(flags);
cli();
c = 0; c = 0;
while (c < count) while (c < count)
...@@ -308,6 +299,8 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count) ...@@ -308,6 +299,8 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
/* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */ /* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
/* yes, think the same, so I removed the cli() brackets
QUEUE_BYTE is protected against interrupts */
if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) { if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) {
c = -EFAULT; c = -EFAULT;
goto out; goto out;
...@@ -317,7 +310,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count) ...@@ -317,7 +310,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
} }
} }
out: out:
restore_flags(flags);
return c; return c;
} }
...@@ -325,14 +317,10 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count) ...@@ -325,14 +317,10 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
int MIDIbuf_read(int dev, struct file *file, char *buf, int count) int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
{ {
int n, c = 0; int n, c = 0;
unsigned long flags;
unsigned char tmp_data; unsigned char tmp_data;
dev = dev >> 4; dev = dev >> 4;
save_flags(flags);
cli();
if (!DATA_AVAIL(midi_in_buf[dev])) { /* if (!DATA_AVAIL(midi_in_buf[dev])) { /*
* No data yet, wait * No data yet, wait
*/ */
...@@ -361,6 +349,8 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count) ...@@ -361,6 +349,8 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
REMOVE_BYTE(midi_in_buf[dev], tmp_data); REMOVE_BYTE(midi_in_buf[dev], tmp_data);
fixit = (char *) &tmp_data; fixit = (char *) &tmp_data;
/* BROKE BROKE BROKE */ /* BROKE BROKE BROKE */
/* yes removed the cli() brackets again
should q->len,tail&head be atomic_t? */
if (copy_to_user(&(buf)[c], fixit, 1)) { if (copy_to_user(&(buf)[c], fixit, 1)) {
c = -EFAULT; c = -EFAULT;
goto out; goto out;
...@@ -369,7 +359,6 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count) ...@@ -369,7 +359,6 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
} }
} }
out: out:
restore_flags(flags);
return c; return c;
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#define USE_SEQ_MACROS #define USE_SEQ_MACROS
#define USE_SIMPLE_MACROS #define USE_SIMPLE_MACROS
...@@ -68,6 +68,7 @@ struct mpu_config ...@@ -68,6 +68,7 @@ struct mpu_config
void (*inputintr) (int dev, unsigned char data); void (*inputintr) (int dev, unsigned char data);
int shared_irq; int shared_irq;
int *osp; int *osp;
spinlock_t lock;
}; };
#define DATAPORT(base) (base) #define DATAPORT(base) (base)
...@@ -408,11 +409,10 @@ static void mpu401_input_loop(struct mpu_config *devc) ...@@ -408,11 +409,10 @@ static void mpu401_input_loop(struct mpu_config *devc)
int busy; int busy;
int n; int n;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
busy = devc->m_busy; busy = devc->m_busy;
devc->m_busy = 1; devc->m_busy = 1;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
if (busy) /* Already inside the scanner */ if (busy) /* Already inside the scanner */
return; return;
...@@ -447,7 +447,6 @@ void mpuintr(int irq, void *dev_id, struct pt_regs *dummy) ...@@ -447,7 +447,6 @@ void mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
struct mpu_config *devc; struct mpu_config *devc;
int dev = (int) dev_id; int dev = (int) dev_id;
sti();
devc = &dev_conf[dev]; devc = &dev_conf[dev];
if (input_avail(devc)) if (input_avail(devc))
...@@ -559,16 +558,15 @@ static int mpu401_out(int dev, unsigned char midi_byte) ...@@ -559,16 +558,15 @@ static int mpu401_out(int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--); for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (!output_ready(devc)) if (!output_ready(devc))
{ {
printk(KERN_WARNING "mpu401: Send data timeout\n"); printk(KERN_WARNING "mpu401: Send data timeout\n");
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return 0; return 0;
} }
write_data(devc, midi_byte); write_data(devc, midi_byte);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return 1; return 1;
} }
...@@ -606,12 +604,11 @@ static int mpu401_command(int dev, mpu_command_rec * cmd) ...@@ -606,12 +604,11 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd); printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd);
return -EIO; return -EIO;
} }
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (!output_ready(devc)) if (!output_ready(devc))
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
goto retry; goto retry;
} }
write_command(devc, cmd->cmd); write_command(devc, cmd->cmd);
...@@ -636,7 +633,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd) ...@@ -636,7 +633,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
} }
if (!ok) if (!ok)
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return -EIO; return -EIO;
} }
if (cmd->nr_args) if (cmd->nr_args)
...@@ -647,7 +644,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd) ...@@ -647,7 +644,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
if (!mpu401_out(dev, cmd->data[i])) if (!mpu401_out(dev, cmd->data[i]))
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
printk(KERN_WARNING "mpu401: Command (0x%x), parm send failed.\n", (int) cmd->cmd); printk(KERN_WARNING "mpu401: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
return -EIO; return -EIO;
} }
...@@ -669,12 +666,12 @@ static int mpu401_command(int dev, mpu_command_rec * cmd) ...@@ -669,12 +666,12 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
} }
if (!ok) if (!ok)
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return -EIO; return -EIO;
} }
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return ret; return ret;
} }
...@@ -941,16 +938,15 @@ static void mpu401_chk_version(int n, struct mpu_config *devc) ...@@ -941,16 +938,15 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
devc->version = devc->revision = 0; devc->version = devc->revision = 0;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0) if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0)
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return; return;
} }
if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */ if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return; return;
} }
devc->version = tmp; devc->version = tmp;
...@@ -958,11 +954,11 @@ static void mpu401_chk_version(int n, struct mpu_config *devc) ...@@ -958,11 +954,11 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0) if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0)
{ {
devc->version = 0; devc->version = 0;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return; return;
} }
devc->revision = tmp; devc->revision = tmp;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
void attach_mpu401(struct address_info *hw_config, struct module *owner) void attach_mpu401(struct address_info *hw_config, struct module *owner)
...@@ -995,6 +991,7 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -995,6 +991,7 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
devc->m_state = ST_INIT; devc->m_state = ST_INIT;
devc->shared_irq = hw_config->always_detect; devc->shared_irq = hw_config->always_detect;
devc->irq = hw_config->irq; devc->irq = hw_config->irq;
spin_lock_init(&devc->lock);
if (devc->irq < 0) if (devc->irq < 0)
{ {
...@@ -1020,12 +1017,11 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -1020,12 +1017,11 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
return; return;
} }
} }
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
mpu401_chk_version(m, devc); mpu401_chk_version(m, devc);
if (devc->version == 0) if (devc->version == 0)
mpu401_chk_version(m, devc); mpu401_chk_version(m, devc);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
request_region(hw_config->io_base, 2, "mpu401"); request_region(hw_config->io_base, 2, "mpu401");
...@@ -1154,12 +1150,11 @@ static int reset_mpu401(struct mpu_config *devc) ...@@ -1154,12 +1150,11 @@ static int reset_mpu401(struct mpu_config *devc)
for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--) for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
{ {
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (input_avail(devc)) if (input_avail(devc))
if (read_data(devc) == MPU_ACK) if (read_data(devc) == MPU_ACK)
ok = 1; ok = 1;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
} }
...@@ -1289,16 +1284,15 @@ static void set_timebase(int midi_dev, int val) ...@@ -1289,16 +1284,15 @@ static void set_timebase(int midi_dev, int val)
} }
static void tmr_reset(void) static void tmr_reset(struct mpu_config *devc)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
next_event_time = (unsigned long) -1; next_event_time = (unsigned long) -1;
prev_event_time = 0; prev_event_time = 0;
curr_ticks = curr_clocks = 0; curr_ticks = curr_clocks = 0;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static void set_timer_mode(int midi_dev) static void set_timer_mode(int midi_dev)
...@@ -1353,7 +1347,9 @@ static void setup_metronome(int midi_dev) ...@@ -1353,7 +1347,9 @@ static void setup_metronome(int midi_dev)
static int mpu_start_timer(int midi_dev) static int mpu_start_timer(int midi_dev)
{ {
tmr_reset(); struct mpu_config *devc= &dev_conf[midi_dev];
tmr_reset(devc);
set_timer_mode(midi_dev); set_timer_mode(midi_dev);
if (tmr_running) if (tmr_running)
...@@ -1378,11 +1374,12 @@ static int mpu_start_timer(int midi_dev) ...@@ -1378,11 +1374,12 @@ static int mpu_start_timer(int midi_dev)
static int mpu_timer_open(int dev, int mode) static int mpu_timer_open(int dev, int mode)
{ {
int midi_dev = sound_timer_devs[dev]->devlink; int midi_dev = sound_timer_devs[dev]->devlink;
struct mpu_config *devc= &dev_conf[midi_dev];
if (timer_open) if (timer_open)
return -EBUSY; return -EBUSY;
tmr_reset(); tmr_reset(devc);
curr_tempo = 50; curr_tempo = 50;
mpu_cmd(midi_dev, 0xE0, 50); mpu_cmd(midi_dev, 0xE0, 50);
curr_timebase = hw_timebase = 120; curr_timebase = hw_timebase = 120;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "nm256.h" #include "nm256.h"
#include "nm256_coeff.h" #include "nm256_coeff.h"
...@@ -262,8 +263,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) ...@@ -262,8 +263,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
return; return;
} }
save_flags (flags); spin_lock_irqsave(&card->lock,flags);
cli ();
/* /*
* If we're not currently recording, set up the start and end registers * If we're not currently recording, set up the start and end registers
* for the recording engine. * for the recording engine.
...@@ -283,7 +283,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) ...@@ -283,7 +283,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
} }
else { else {
/* Not sure what else to do here. */ /* Not sure what else to do here. */
restore_flags (flags); spin_unlock_irqrestore(&card->lock,flags);
return; return;
} }
} }
...@@ -303,7 +303,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) ...@@ -303,7 +303,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG,
NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN); NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);
restore_flags (flags); spin_unlock_irqrestore(&card->lock,flags);
} }
/* Stop the play engine. */ /* Stop the play engine. */
...@@ -370,8 +370,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) ...@@ -370,8 +370,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt)
card->requested_amt = amt; card->requested_amt = amt;
save_flags (flags); spin_lock_irqsave(&card->lock,flags);
cli ();
if ((card->curPlayPos + amt) >= ringsize) { if ((card->curPlayPos + amt) >= ringsize) {
u32 rem = ringsize - card->curPlayPos; u32 rem = ringsize - card->curPlayPos;
...@@ -418,7 +417,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) ...@@ -418,7 +417,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt)
if (! card->playing) if (! card->playing)
startPlay (card); startPlay (card);
restore_flags (flags); spin_unlock_irqrestore(&card->lock,flags);
} }
/* We just got a card playback interrupt; process it. */ /* We just got a card playback interrupt; process it. */
...@@ -829,8 +828,7 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) ...@@ -829,8 +828,7 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value)
base = card->mixer; base = card->mixer;
save_flags (flags); spin_lock_irqsave(&card->lock,flags);
cli ();
nm256_isReady (dev); nm256_isReady (dev);
...@@ -844,7 +842,7 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) ...@@ -844,7 +842,7 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value)
} }
restore_flags (flags); spin_unlock_irqrestore(&card->lock,flags);
udelay (1000); udelay (1000);
return ! done; return ! done;
...@@ -1055,6 +1053,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) ...@@ -1055,6 +1053,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr)
card->playing = 0; card->playing = 0;
card->recording = 0; card->recording = 0;
card->rev = rev; card->rev = rev;
spin_lock_init(&card->lock);
/* Init the memory port info. */ /* Init the memory port info. */
for (x = 0; x < 2; x++) { for (x = 0; x < 2; x++) {
......
...@@ -14,10 +14,13 @@ ...@@ -14,10 +14,13 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "pas2.h" #include "pas2.h"
extern spinlock_t lock;
static int midi_busy = 0, input_opened = 0; static int midi_busy = 0, input_opened = 0;
static int my_dev; static int my_dev;
...@@ -48,12 +51,11 @@ static int pas_midi_open(int dev, int mode, ...@@ -48,12 +51,11 @@ static int pas_midi_open(int dev, int mode,
pas_write(0x20 | 0x40, pas_write(0x20 | 0x40,
0x178b); 0x178b);
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if ((err = pas_set_intr(0x10)) < 0) if ((err = pas_set_intr(0x10)) < 0)
{ {
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
return err; return err;
} }
/* /*
...@@ -81,7 +83,7 @@ static int pas_midi_open(int dev, int mode, ...@@ -81,7 +83,7 @@ static int pas_midi_open(int dev, int mode,
pas_write(0xff, 0x1B88); pas_write(0xff, 0x1B88);
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
midi_busy = 1; midi_busy = 1;
qlen = qhead = qtail = 0; qlen = qhead = qtail = 0;
...@@ -131,8 +133,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte) ...@@ -131,8 +133,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
* Drain the local queue first * Drain the local queue first
*/ */
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
while (qlen && dump_to_midi(tmp_queue[qhead])) while (qlen && dump_to_midi(tmp_queue[qhead]))
{ {
...@@ -140,7 +141,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte) ...@@ -140,7 +141,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
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.
...@@ -157,14 +158,13 @@ static int pas_midi_out(int dev, unsigned char midi_byte) ...@@ -157,14 +158,13 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
if (qlen >= 256) if (qlen >= 256)
return 0; /* Local queue full */ return 0; /* 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;
} }
...@@ -226,7 +226,6 @@ void pas_midi_interrupt(void) ...@@ -226,7 +226,6 @@ void pas_midi_interrupt(void)
{ {
unsigned char stat; unsigned char stat;
int i, incount; int i, incount;
unsigned long flags;
stat = pas_read(0x1B88); stat = pas_read(0x1B88);
...@@ -245,8 +244,7 @@ void pas_midi_interrupt(void) ...@@ -245,8 +244,7 @@ void pas_midi_interrupt(void)
} }
if (stat & (0x08 | 0x10)) if (stat & (0x08 | 0x10))
{ {
save_flags(flags); spin_lock(&lock);/* called in irq context */
cli();
while (qlen && dump_to_midi(tmp_queue[qhead])) while (qlen && dump_to_midi(tmp_queue[qhead]))
{ {
...@@ -254,7 +252,7 @@ void pas_midi_interrupt(void) ...@@ -254,7 +252,7 @@ void pas_midi_interrupt(void)
qhead++; qhead++;
} }
restore_flags(flags); spin_unlock(&lock);
} }
if (stat & 0x40) if (stat & 0x40)
{ {
......
...@@ -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 "pas2.h" #include "pas2.h"
...@@ -44,6 +45,8 @@ static int pcm_busy = 0; ...@@ -44,6 +45,8 @@ static int pcm_busy = 0;
int pas_audiodev = -1; int pas_audiodev = -1;
static int open_mode = 0; static int open_mode = 0;
extern spinlock_t lock;
static int pcm_set_speed(int arg) static int pcm_set_speed(int arg)
{ {
int foo, tmp; int foo, tmp;
...@@ -101,8 +104,7 @@ static int pcm_set_speed(int arg) ...@@ -101,8 +104,7 @@ static int pcm_set_speed(int arg)
pcm_filter = tmp; pcm_filter = tmp;
#endif #endif
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
pas_write(tmp & ~(0x40 | 0x80), 0x0B8A); pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
pas_write(0x00 | 0x30 | 0x04, 0x138B); pas_write(0x00 | 0x30 | 0x04, 0x138B);
...@@ -110,7 +112,7 @@ static int pcm_set_speed(int arg) ...@@ -110,7 +112,7 @@ static int pcm_set_speed(int arg)
pas_write((foo >> 8) & 0xff, 0x1388); pas_write((foo >> 8) & 0xff, 0x1388);
pas_write(tmp, 0x0B8A); pas_write(tmp, 0x0B8A);
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
return pcm_speed; return pcm_speed;
} }
...@@ -212,15 +214,14 @@ static int pas_audio_open(int dev, int mode) ...@@ -212,15 +214,14 @@ static int pas_audio_open(int dev, int mode)
DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode)); DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (pcm_busy) if (pcm_busy)
{ {
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
return -EBUSY; return -EBUSY;
} }
pcm_busy = 1; pcm_busy = 1;
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0) if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
return err; return err;
...@@ -238,15 +239,14 @@ static void pas_audio_close(int dev) ...@@ -238,15 +239,14 @@ static void pas_audio_close(int dev)
DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n")); DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
pas_audio_reset(dev); pas_audio_reset(dev);
pas_remove_intr(PAS_PCM_INTRBITS); pas_remove_intr(PAS_PCM_INTRBITS);
pcm_mode = PCM_NON; pcm_mode = PCM_NON;
pcm_busy = 0; pcm_busy = 0;
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
} }
static void pas_audio_output_block(int dev, unsigned long buf, int count, static void pas_audio_output_block(int dev, unsigned long buf, int count,
...@@ -265,8 +265,7 @@ static void pas_audio_output_block(int dev, unsigned long buf, int count, ...@@ -265,8 +265,7 @@ static void pas_audio_output_block(int dev, unsigned long buf, int count,
cnt == pcm_count) cnt == pcm_count)
return; return;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
pas_write(pas_read(0xF8A) & ~0x40, pas_write(pas_read(0xF8A) & ~0x40,
0xF8A); 0xF8A);
...@@ -293,7 +292,7 @@ static void pas_audio_output_block(int dev, unsigned long buf, int count, ...@@ -293,7 +292,7 @@ static void pas_audio_output_block(int dev, unsigned long buf, int count,
pcm_mode = PCM_DAC; pcm_mode = PCM_DAC;
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
} }
static void pas_audio_start_input(int dev, unsigned long buf, int count, static void pas_audio_start_input(int dev, unsigned long buf, int count,
...@@ -313,8 +312,7 @@ static void pas_audio_start_input(int dev, unsigned long buf, int count, ...@@ -313,8 +312,7 @@ static void pas_audio_start_input(int dev, unsigned long buf, int count,
cnt == pcm_count) cnt == pcm_count)
return; return;
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); */
...@@ -338,7 +336,7 @@ static void pas_audio_start_input(int dev, unsigned long buf, int count, ...@@ -338,7 +336,7 @@ static void pas_audio_start_input(int dev, unsigned long buf, int count,
pcm_mode = PCM_ADC; pcm_mode = PCM_ADC;
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
} }
#ifndef NO_TRIGGER #ifndef NO_TRIGGER
...@@ -346,8 +344,7 @@ static void pas_audio_trigger(int dev, int state) ...@@ -346,8 +344,7 @@ static void pas_audio_trigger(int dev, int state)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
state &= open_mode; state &= open_mode;
if (state & PCM_ENABLE_OUTPUT) if (state & PCM_ENABLE_OUTPUT)
...@@ -357,7 +354,7 @@ static void pas_audio_trigger(int dev, int state) ...@@ -357,7 +354,7 @@ static void pas_audio_trigger(int dev, int state)
else else
pas_write(pas_read(0xF8A) & ~0x40, 0xF8A); pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
restore_flags(flags); spin_unlock_irqrestore(&lock, flags);
} }
#endif #endif
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "sound_firmware.h" #include "sound_firmware.h"
...@@ -142,6 +143,7 @@ typedef struct pss_confdata { ...@@ -142,6 +143,7 @@ typedef struct pss_confdata {
static pss_confdata pss_data; static pss_confdata pss_data;
static pss_confdata *devc = &pss_data; static pss_confdata *devc = &pss_data;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
static int pss_initialized = 0; static int pss_initialized = 0;
static int nonstandard_microcode = 0; static int nonstandard_microcode = 0;
...@@ -838,18 +840,17 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l ...@@ -838,18 +840,17 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
return -EFAULT; return -EFAULT;
} }
data = (unsigned short *)(mbuf->data); data = (unsigned short *)(mbuf->data);
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
for (i = 0; i < mbuf->len; i++) { for (i = 0; i < mbuf->len; i++) {
if (!pss_put_dspword(devc, *data++)) { if (!pss_put_dspword(devc, *data++)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
mbuf->len = i; /* feed back number of WORDs sent */ mbuf->len = i; /* feed back number of WORDs sent */
err = copy_to_user(arg, mbuf, sizeof(copr_msg)); err = copy_to_user(arg, mbuf, sizeof(copr_msg));
vfree(mbuf); vfree(mbuf);
return err ? -EFAULT : -EIO; return err ? -EFAULT : -EIO;
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
vfree(mbuf); vfree(mbuf);
return 0; return 0;
...@@ -859,8 +860,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l ...@@ -859,8 +860,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
if (mbuf == NULL) if (mbuf == NULL)
return -ENOSPC; return -ENOSPC;
data = (unsigned short *)mbuf->data; data = (unsigned short *)mbuf->data;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) { for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
mbuf->len = i; /* feed back number of WORDs read */ mbuf->len = i; /* feed back number of WORDs read */
if (!pss_get_dspword(devc, data++)) { if (!pss_get_dspword(devc, data++)) {
...@@ -869,7 +869,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l ...@@ -869,7 +869,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
break; break;
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, mbuf, sizeof(copr_msg))) if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
err = -EFAULT; err = -EFAULT;
vfree(mbuf); vfree(mbuf);
...@@ -878,22 +878,21 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l ...@@ -878,22 +878,21 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
case SNDCTL_COPR_RDATA: case SNDCTL_COPR_RDATA:
if (copy_from_user(&dbuf, arg, sizeof(dbuf))) if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (!pss_put_dspword(devc, 0x00d0)) { if (!pss_put_dspword(devc, 0x00d0)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) { if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_get_dspword(devc, &tmp)) { if (!pss_get_dspword(devc, &tmp)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
dbuf.parm1 = tmp; dbuf.parm1 = tmp;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, &dbuf, sizeof(dbuf))) if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -901,74 +900,71 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l ...@@ -901,74 +900,71 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
case SNDCTL_COPR_WDATA: case SNDCTL_COPR_WDATA:
if (copy_from_user(&dbuf, arg, sizeof(dbuf))) if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (!pss_put_dspword(devc, 0x00d1)) { if (!pss_put_dspword(devc, 0x00d1)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) { if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
tmp = (unsigned int)dbuf.parm2 & 0xffff; tmp = (unsigned int)dbuf.parm2 & 0xffff;
if (!pss_put_dspword(devc, tmp)) { if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
case SNDCTL_COPR_WCODE: case SNDCTL_COPR_WCODE:
if (copy_from_user(&dbuf, arg, sizeof(dbuf))) if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (!pss_put_dspword(devc, 0x00d3)) { if (!pss_put_dspword(devc, 0x00d3)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) { if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
tmp = (unsigned int)dbuf.parm2 & 0x00ff; tmp = (unsigned int)dbuf.parm2 & 0x00ff;
if (!pss_put_dspword(devc, tmp)) { if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff; tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
if (!pss_put_dspword(devc, tmp)) { if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
case SNDCTL_COPR_RCODE: case SNDCTL_COPR_RCODE:
if (copy_from_user(&dbuf, arg, sizeof(dbuf))) if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock, flags);
cli();
if (!pss_put_dspword(devc, 0x00d2)) { if (!pss_put_dspword(devc, 0x00d2)) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) { if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */ if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
dbuf.parm1 = tmp << 8; dbuf.parm1 = tmp << 8;
if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */ if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return -EIO; return -EIO;
} }
dbuf.parm1 |= tmp & 0x00ff; dbuf.parm1 |= tmp & 0x00ff;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, &dbuf, sizeof(dbuf))) if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
return -EFAULT; return -EFAULT;
return 0; return 0;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Alan Cox : reformatted and fixed a pair of null pointer bugs * Alan Cox : reformatted and fixed a pair of null pointer bugs
*/ */
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/spinlock.h>
#define SEQUENCER_C #define SEQUENCER_C
#include "sound_config.h" #include "sound_config.h"
...@@ -28,6 +28,7 @@ static int pending_timer = -1; /* For timer change operation */ ...@@ -28,6 +28,7 @@ static int pending_timer = -1; /* For timer change operation */
extern unsigned long seq_time; extern unsigned long seq_time;
static int obsolete_api_used = 0; static int obsolete_api_used = 0;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
/* /*
* Local counts for number of synth and MIDI devices. These are initialized * Local counts for number of synth and MIDI devices. These are initialized
...@@ -95,37 +96,38 @@ int sequencer_read(int dev, struct file *file, char *buf, int count) ...@@ -95,37 +96,38 @@ int sequencer_read(int dev, struct file *file, char *buf, int count)
ev_len = seq_mode == SEQ_1 ? 4 : 8; ev_len = seq_mode == SEQ_1 ? 4 : 8;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
if (!iqlen) if (!iqlen)
{ {
spin_unlock_irqrestore(&lock,flags);
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
restore_flags(flags);
return -EAGAIN; return -EAGAIN;
} }
interruptible_sleep_on_timeout(&midi_sleeper, interruptible_sleep_on_timeout(&midi_sleeper,
pre_event_timeout); pre_event_timeout);
spin_lock_irqsave(&lock,flags);
if (!iqlen) if (!iqlen)
{ {
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
} }
} }
while (iqlen && c >= ev_len) while (iqlen && c >= ev_len)
{ {
char *fixit = (char *) &iqueue[iqhead * IEV_SZ]; char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(&(buf)[p], fixit, ev_len)) if (copy_to_user(&(buf)[p], fixit, ev_len))
goto out; return count - c;
p += ev_len; p += ev_len;
c -= ev_len; c -= ev_len;
spin_lock_irqsave(&lock,flags);
iqhead = (iqhead + 1) % SEQ_MAX_QUEUE; iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
iqlen--; iqlen--;
} }
out: spin_unlock_irqrestore(&lock,flags);
restore_flags(flags);
return count - c; return count - c;
} }
...@@ -152,13 +154,12 @@ void seq_copy_to_input(unsigned char *event_rec, int len) ...@@ -152,13 +154,12 @@ void seq_copy_to_input(unsigned char *event_rec, int len)
if (iqlen >= (SEQ_MAX_QUEUE - 1)) if (iqlen >= (SEQ_MAX_QUEUE - 1))
return; /* Overflow */ return; /* Overflow */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len); memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len);
iqlen++; iqlen++;
iqtail = (iqtail + 1) % SEQ_MAX_QUEUE; iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
wake_up(&midi_sleeper); wake_up(&midi_sleeper);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void sequencer_midi_input(int dev, unsigned char data) static void sequencer_midi_input(int dev, unsigned char data)
...@@ -869,19 +870,19 @@ static int play_event(unsigned char *q) ...@@ -869,19 +870,19 @@ static int play_event(unsigned char *q)
return 0; return 0;
} }
/* called also as timer in irq context */
static void seq_startplay(void) static void seq_startplay(void)
{ {
unsigned long flags;
int this_one, action; int this_one, action;
unsigned long flags;
while (qlen > 0) while (qlen > 0)
{ {
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE; qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
qlen--; qlen--;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
seq_playing = 1; seq_playing = 1;
...@@ -947,7 +948,6 @@ int sequencer_open(int dev, struct file *file) ...@@ -947,7 +948,6 @@ int sequencer_open(int dev, struct file *file)
{ {
int retval, mode, i; int retval, mode, i;
int level, tmp; int level, tmp;
unsigned long flags;
if (!sequencer_ok) if (!sequencer_ok)
sequencer_init(); sequencer_init();
...@@ -979,16 +979,12 @@ int sequencer_open(int dev, struct file *file) ...@@ -979,16 +979,12 @@ int sequencer_open(int dev, struct file *file)
return -ENXIO; return -ENXIO;
} }
} }
save_flags(flags);
cli();
if (sequencer_busy) if (sequencer_busy)
{ {
restore_flags(flags);
return -EBUSY; return -EBUSY;
} }
sequencer_busy = 1; sequencer_busy = 1;
obsolete_api_used = 0; obsolete_api_used = 0;
restore_flags(flags);
max_mididev = num_midis; max_mididev = num_midis;
max_synthdev = num_synths; max_synthdev = num_synths;
...@@ -1203,16 +1199,11 @@ void sequencer_release(int dev, struct file *file) ...@@ -1203,16 +1199,11 @@ void sequencer_release(int dev, struct file *file)
static int seq_sync(void) static int seq_sync(void)
{ {
unsigned long flags;
if (qlen && !seq_playing && !signal_pending(current)) if (qlen && !seq_playing && !signal_pending(current))
seq_startplay(); seq_startplay();
save_flags(flags);
cli();
if (qlen > 0) if (qlen > 0)
interruptible_sleep_on_timeout(&seq_sleeper, HZ); interruptible_sleep_on_timeout(&seq_sleeper, HZ);
restore_flags(flags);
return qlen; return qlen;
} }
...@@ -1233,13 +1224,12 @@ static void midi_outc(int dev, unsigned char data) ...@@ -1233,13 +1224,12 @@ static void midi_outc(int dev, unsigned char data)
n = 3 * HZ; /* Timeout */ n = 3 * HZ; /* Timeout */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
while (n && !midi_devs[dev]->outputc(dev, data)) { while (n && !midi_devs[dev]->outputc(dev, data)) {
interruptible_sleep_on_timeout(&seq_sleeper, HZ/25); interruptible_sleep_on_timeout(&seq_sleeper, HZ/25);
n--; n--;
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void seq_reset(void) static void seq_reset(void)
...@@ -1308,14 +1298,13 @@ static void seq_reset(void) ...@@ -1308,14 +1298,13 @@ static void seq_reset(void)
seq_playing = 0; seq_playing = 0;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
if (waitqueue_active(&seq_sleeper)) { if (waitqueue_active(&seq_sleeper)) {
/* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */ /* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
wake_up(&seq_sleeper); wake_up(&seq_sleeper);
} }
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static void seq_panic(void) static void seq_panic(void)
...@@ -1499,10 +1488,9 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg) ...@@ -1499,10 +1488,9 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
case SNDCTL_SEQ_OUTOFBAND: case SNDCTL_SEQ_OUTOFBAND:
if (copy_from_user(&event_rec, arg, sizeof(event_rec))) if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
return -EFAULT; return -EFAULT;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
play_event(event_rec.arr); play_event(event_rec.arr);
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return 0; return 0;
case SNDCTL_MIDI_INFO: case SNDCTL_MIDI_INFO:
...@@ -1554,8 +1542,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait) ...@@ -1554,8 +1542,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
dev = dev >> 4; dev = dev >> 4;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
/* input */ /* input */
poll_wait(file, &midi_sleeper, wait); poll_wait(file, &midi_sleeper, wait);
if (iqlen) if (iqlen)
...@@ -1565,7 +1552,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait) ...@@ -1565,7 +1552,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
poll_wait(file, &seq_sleeper, wait); poll_wait(file, &seq_sleeper, wait);
if ((SEQ_MAX_QUEUE - qlen) >= output_threshold) if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
mask |= POLLOUT | POLLWRNORM; mask |= POLLOUT | POLLWRNORM;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
return mask; return mask;
} }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/wrapper.h> #include <linux/wrapper.h>
#include <linux/spinlock.h>
#include "coproc.h" #include "coproc.h"
...@@ -115,7 +116,7 @@ typedef struct sscape_info ...@@ -115,7 +116,7 @@ typedef struct sscape_info
char* raw_buf; char* raw_buf;
unsigned long raw_buf_phys; unsigned long raw_buf_phys;
int buffsize; /* -------------------------- */ int buffsize; /* -------------------------- */
spinlock_t lock;
int ok; /* Properly detected */ int ok; /* Properly detected */
int failed; int failed;
int dma_allocated; int dma_allocated;
...@@ -164,11 +165,10 @@ static unsigned char sscape_read(struct sscape_info *devc, int reg) ...@@ -164,11 +165,10 @@ static unsigned char sscape_read(struct sscape_info *devc, int reg)
unsigned long flags; unsigned long flags;
unsigned char val; unsigned char val;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
outb(reg, PORT(ODIE_ADDR)); outb(reg, PORT(ODIE_ADDR));
val = inb(PORT(ODIE_DATA)); val = inb(PORT(ODIE_DATA));
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return val; return val;
} }
...@@ -176,11 +176,10 @@ static void sscape_write(struct sscape_info *devc, int reg, int data) ...@@ -176,11 +176,10 @@ static void sscape_write(struct sscape_info *devc, int reg, int data)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
outb(reg, PORT(ODIE_ADDR)); outb(reg, PORT(ODIE_ADDR));
outb(data, PORT(ODIE_DATA)); outb(data, PORT(ODIE_DATA));
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg) static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
...@@ -188,11 +187,10 @@ static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg) ...@@ -188,11 +187,10 @@ static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
unsigned char res; unsigned char res;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
outb( reg, devc -> codec); outb( reg, devc -> codec);
res = inb (devc -> codec + 1); res = inb (devc -> codec + 1);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return res; return res;
} }
...@@ -201,11 +199,10 @@ static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigne ...@@ -201,11 +199,10 @@ static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigne
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
outb( reg, devc -> codec); outb( reg, devc -> codec);
outb( data, devc -> codec + 1); outb( data, devc -> codec + 1);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static void host_open(struct sscape_info *devc) static void host_open(struct sscape_info *devc)
...@@ -223,9 +220,7 @@ static int host_write(struct sscape_info *devc, unsigned char *data, int count) ...@@ -223,9 +220,7 @@ static int host_write(struct sscape_info *devc, unsigned char *data, int count)
unsigned long flags; unsigned long flags;
int i, timeout_val; int i, timeout_val;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
/* /*
* Send the command and data bytes * Send the command and data bytes
*/ */
...@@ -238,12 +233,12 @@ static int host_write(struct sscape_info *devc, unsigned char *data, int count) ...@@ -238,12 +233,12 @@ static int host_write(struct sscape_info *devc, unsigned char *data, int count)
if (timeout_val <= 0) if (timeout_val <= 0)
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return 0; return 0;
} }
outb(data[i], PORT(HOST_DATA)); outb(data[i], PORT(HOST_DATA));
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return 1; return 1;
} }
...@@ -253,9 +248,7 @@ static int host_read(struct sscape_info *devc) ...@@ -253,9 +248,7 @@ static int host_read(struct sscape_info *devc)
int timeout_val; int timeout_val;
unsigned char data; unsigned char data;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
/* /*
* Read a byte * Read a byte
*/ */
...@@ -266,11 +259,11 @@ static int host_read(struct sscape_info *devc) ...@@ -266,11 +259,11 @@ static int host_read(struct sscape_info *devc)
if (timeout_val <= 0) if (timeout_val <= 0)
{ {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return -1; return -1;
} }
data = inb(PORT(HOST_DATA)); data = inb(PORT(HOST_DATA));
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return data; return data;
} }
...@@ -391,14 +384,13 @@ static void sscape_coproc_close(void *dev_info, int sub_device) ...@@ -391,14 +384,13 @@ static void sscape_coproc_close(void *dev_info, int sub_device)
struct sscape_info *devc = dev_info; struct sscape_info *devc = dev_info;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (devc->dma_allocated) if (devc->dma_allocated)
{ {
sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */ sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
devc->dma_allocated = 0; devc->dma_allocated = 0;
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return; return;
} }
...@@ -420,14 +412,13 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -420,14 +412,13 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
* before continuing. * before continuing.
*/ */
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
codec_dma_bits = sscape_read(devc, GA_CDCFG_REG); codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
if (devc->dma_allocated == 0) if (devc->dma_allocated == 0)
devc->dma_allocated = 1; devc->dma_allocated = 1;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
sscape_write(devc, GA_HMCTL_REG, sscape_write(devc, GA_HMCTL_REG,
(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */ (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
...@@ -449,8 +440,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -449,8 +440,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
} }
memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size); memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
/******** INTERRUPTS DISABLED NOW ********/ /******** INTERRUPTS DISABLED NOW ********/
...@@ -475,7 +465,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -475,7 +465,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
done = 1; done = 1;
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
if (!done) if (!done)
return 0; return 0;
...@@ -494,9 +484,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -494,9 +484,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
/* /*
* Wait until the ODB wakes up * Wait until the ODB wakes up
*/ */
spin_lock_irqsave(&devc->lock,flags);
save_flags(flags);
cli();
done = 0; done = 0;
timeout_val = 5 * HZ; timeout_val = 5 * HZ;
while (!done && timeout_val-- > 0) while (!done && timeout_val-- > 0)
...@@ -513,14 +501,13 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -513,14 +501,13 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
} }
sscape_write(devc, GA_CDCFG_REG, codec_dma_bits); sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
if (!done) if (!done)
{ {
printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n"); printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
return 0; return 0;
} }
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
done = 0; done = 0;
timeout_val = 5 * HZ; timeout_val = 5 * HZ;
while (!done && timeout_val-- > 0) while (!done && timeout_val-- > 0)
...@@ -529,7 +516,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, ...@@ -529,7 +516,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */ if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
done = 1; done = 1;
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
if (!done) if (!done)
{ {
printk(KERN_ERR "soundscape: OBP Initialization failed.\n"); printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
...@@ -675,8 +662,7 @@ void __init attach_sscape(struct address_info *hw_config) ...@@ -675,8 +662,7 @@ void __init attach_sscape(struct address_info *hw_config)
if (!sscape_is_pnp) { if (!sscape_is_pnp) {
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
for (i = 1; i < 10; i++) for (i = 1; i < 10; i++)
{ {
switch (i) switch (i)
...@@ -710,7 +696,7 @@ void __init attach_sscape(struct address_info *hw_config) ...@@ -710,7 +696,7 @@ void __init attach_sscape(struct address_info *hw_config)
sscape_write(devc, i, regs[i]); sscape_write(devc, i, regs[i]);
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
#ifdef SSCAPE_DEBUG2 #ifdef SSCAPE_DEBUG2
/* /*
...@@ -960,8 +946,7 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn) ...@@ -960,8 +946,7 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
return 0; return 0;
} }
dt = data; dt = data;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
while ( len > 0 ) { while ( len > 0 ) {
if (len > devc -> buffsize) l = devc->buffsize; if (len > devc -> buffsize) l = devc->buffsize;
else l = len; else l = len;
...@@ -970,12 +955,12 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn) ...@@ -970,12 +955,12 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48); sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
sscape_pnp_start_dma ( devc, 0 ); sscape_pnp_start_dma ( devc, 0 );
if (sscape_pnp_wait_dma ( devc, 0 ) == 0) { if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
return 0; return 0;
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
vfree(data); vfree(data);
outb(0, devc -> base + 2); outb(0, devc -> base + 2);
...@@ -1469,6 +1454,7 @@ static int __init init_sscape(void) ...@@ -1469,6 +1454,7 @@ static int __init init_sscape(void)
devc->codec_type = 0; devc->codec_type = 0;
devc->ic_type = 0; devc->ic_type = 0;
devc->raw_buf = NULL; devc->raw_buf = NULL;
spin_lock_init(&devc->lock);
if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) { if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n"); printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "mpu401.h" #include "mpu401.h"
...@@ -38,6 +38,7 @@ typedef struct uart401_devc ...@@ -38,6 +38,7 @@ typedef struct uart401_devc
volatile unsigned char input_byte; volatile unsigned char input_byte;
int my_dev; int my_dev;
int share_irq; int share_irq;
spinlock_t lock;
} }
uart401_devc; uart401_devc;
...@@ -152,13 +153,11 @@ static int uart401_out(int dev, unsigned char midi_byte) ...@@ -152,13 +153,11 @@ static int uart401_out(int dev, unsigned char midi_byte)
* Test for input since pending input seems to block the output. * Test for input since pending input seems to block the output.
*/ */
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (input_avail(devc)) if (input_avail(devc))
uart401_input_loop(devc); uart401_input_loop(devc);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
/* /*
* Sometimes it takes about 13000 loops before the output becomes ready * Sometimes it takes about 13000 loops before the output becomes ready
...@@ -222,8 +221,7 @@ static void enter_uart_mode(uart401_devc * devc) ...@@ -222,8 +221,7 @@ static void enter_uart_mode(uart401_devc * devc)
int ok, timeout; int ok, timeout;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--); for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
devc->input_byte = 0; devc->input_byte = 0;
...@@ -237,7 +235,7 @@ static void enter_uart_mode(uart401_devc * devc) ...@@ -237,7 +235,7 @@ static void enter_uart_mode(uart401_devc * devc)
if (uart401_read(devc) == MPU_ACK) if (uart401_read(devc) == MPU_ACK)
ok = 1; ok = 1;
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static int reset_uart401(uart401_devc * devc) static int reset_uart401(uart401_devc * devc)
...@@ -320,11 +318,11 @@ int probe_uart401(struct address_info *hw_config, struct module *owner) ...@@ -320,11 +318,11 @@ int probe_uart401(struct address_info *hw_config, struct module *owner)
devc->input_byte = 0; devc->input_byte = 0;
devc->my_dev = 0; devc->my_dev = 0;
devc->share_irq = 0; devc->share_irq = 0;
spin_lock_init(&devc->lock);
save_flags(flags); spin_lock_irqsave(&devc->lock,flags);
cli();
ok = reset_uart401(devc); ok = reset_uart401(devc);
restore_flags(flags); spin_unlock_irqrestore(&devc->lock,flags);
if (!ok) if (!ok)
goto cleanup_devc; goto cleanup_devc;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h>
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl: /* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
* added 6850 support, used with COVOX SoundMaster II and custom cards. * added 6850 support, used with COVOX SoundMaster II and custom cards.
*/ */
...@@ -71,6 +71,7 @@ static int uart6850_opened; ...@@ -71,6 +71,7 @@ static int uart6850_opened;
static int uart6850_irq; static int uart6850_irq;
static int uart6850_detected; static int uart6850_detected;
static int my_dev; static int my_dev;
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 void poll_uart6850(unsigned long dummy); static void poll_uart6850(unsigned long dummy);
...@@ -122,9 +123,7 @@ static void poll_uart6850(unsigned long dummy) ...@@ -122,9 +123,7 @@ static void poll_uart6850(unsigned long dummy)
if (!(uart6850_opened & OPEN_READ)) if (!(uart6850_opened & OPEN_READ))
return; /* Device has been closed */ return; /* Device has been closed */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
if (input_avail()) if (input_avail())
uart6850_input_loop(); uart6850_input_loop();
...@@ -135,7 +134,7 @@ static void poll_uart6850(unsigned long dummy) ...@@ -135,7 +134,7 @@ static void poll_uart6850(unsigned long dummy)
* Come back later * Come back later
*/ */
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
} }
static int uart6850_open(int dev, int mode, static int uart6850_open(int dev, int mode,
...@@ -176,13 +175,12 @@ static int uart6850_out(int dev, unsigned char midi_byte) ...@@ -176,13 +175,12 @@ static int uart6850_out(int dev, unsigned char midi_byte)
* Test for input since pending input seems to block the output. * Test for input since pending input seems to block the output.
*/ */
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
if (input_avail()) if (input_avail())
uart6850_input_loop(); uart6850_input_loop();
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
/* /*
* Sometimes it takes about 13000 loops before the output becomes ready * Sometimes it takes about 13000 loops before the output becomes ready
...@@ -265,15 +263,14 @@ static void __init attach_uart6850(struct address_info *hw_config) ...@@ -265,15 +263,14 @@ static void __init attach_uart6850(struct address_info *hw_config)
uart6850_osp = hw_config->osp; uart6850_osp = hw_config->osp;
uart6850_irq = hw_config->irq; uart6850_irq = hw_config->irq;
save_flags(flags); spin_lock_irqsave(&lock,flags);
cli();
for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /* for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /*
* Wait * Wait
*/ */
uart6850_cmd(UART_MODE_ON); uart6850_cmd(UART_MODE_ON);
ok = 1; ok = 1;
restore_flags(flags); spin_unlock_irqrestore(&lock,flags);
conf_printf("6850 Midi Interface", hw_config); conf_printf("6850 Midi Interface", hw_config);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h" #include "sound_config.h"
#include "v_midi.h" #include "v_midi.h"
...@@ -52,15 +52,14 @@ static int v_midi_open (int dev, int mode, ...@@ -52,15 +52,14 @@ static int v_midi_open (int dev, int mode,
if (devc == NULL) if (devc == NULL)
return -(ENXIO); return -(ENXIO);
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli();
if (devc->opened) if (devc->opened)
{ {
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
return -(EBUSY); return -(EBUSY);
} }
devc->opened = 1; devc->opened = 1;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
devc->intr_active = 1; devc->intr_active = 1;
...@@ -81,12 +80,11 @@ static void v_midi_close (int dev) ...@@ -81,12 +80,11 @@ static void v_midi_close (int dev)
if (devc == NULL) if (devc == NULL)
return; return;
save_flags (flags); spin_lock_irqsave(&devc->lock,flags);
cli ();
devc->intr_active = 0; devc->intr_active = 0;
devc->input_opened = 0; devc->input_opened = 0;
devc->opened = 0; devc->opened = 0;
restore_flags (flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
static int v_midi_out (int dev, unsigned char midi_byte) static int v_midi_out (int dev, unsigned char midi_byte)
...@@ -222,6 +220,7 @@ static void __init attach_v_midi (struct address_info *hw_config) ...@@ -222,6 +220,7 @@ static void __init attach_v_midi (struct address_info *hw_config)
v_devc[0]->opened = v_devc[0]->input_opened = 0; v_devc[0]->opened = v_devc[0]->input_opened = 0;
v_devc[0]->intr_active = 0; v_devc[0]->intr_active = 0;
v_devc[0]->midi_input_intr = NULL; v_devc[0]->midi_input_intr = NULL;
spin_lock_init(&v_devc[0]->lock);
midi_devs[midi1]->devc = v_devc[0]; midi_devs[midi1]->devc = v_devc[0];
...@@ -242,6 +241,7 @@ static void __init attach_v_midi (struct address_info *hw_config) ...@@ -242,6 +241,7 @@ static void __init attach_v_midi (struct address_info *hw_config)
v_devc[1]->opened = v_devc[1]->input_opened = 0; v_devc[1]->opened = v_devc[1]->input_opened = 0;
v_devc[1]->intr_active = 0; v_devc[1]->intr_active = 0;
v_devc[1]->midi_input_intr = NULL; v_devc[1]->midi_input_intr = NULL;
spin_lock_init(&v_devc[1]->lock);
midi_devs[midi2]->devc = v_devc[1]; midi_devs[midi2]->devc = v_devc[1];
midi_devs[midi2]->converter = &m->s_ops[1]; midi_devs[midi2]->converter = &m->s_ops[1];
......
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