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 @@
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#define DEBUGNOISE(x)
......@@ -77,7 +77,7 @@ typedef struct
in ad1816_info */
int irq_ok;
int *osp;
spinlock_t lock;
} ad1816_info;
static int nr_ad1816_devs;
......@@ -109,12 +109,11 @@ static int ad_read (ad1816_info * devc, int reg)
CHECK_FOR_POWER;
save_flags (flags); /* make register access atomic */
cli ();
spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
outb ((unsigned char) (reg & 0x3f), devc->base+0);
result = inb(devc->base+2);
result+= inb(devc->base+3)<<8;
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
return (result);
}
......@@ -126,12 +125,11 @@ static void ad_write (ad1816_info * devc, int reg, int data)
CHECK_FOR_POWER;
save_flags (flags); /* make register access atomic */
cli ();
spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
outb ((unsigned char) (reg & 0xff), devc->base+0);
outb ((unsigned char) (data & 0xff),devc->base+2);
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)
DEBUGINFO (printk("ad1816: halt_input called\n"));
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
if(!isa_dma_bridge_buggy) {
disable_dma(audio_devs[dev]->dmap_in->dma);
......@@ -168,7 +165,7 @@ static void ad1816_halt_input (int dev)
outb (~0x40, devc->base+1);
devc->audio_mode &= ~PCM_ENABLE_INPUT;
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
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"));
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
/* Mute pcm output */
ad_write(devc, 4, ad_read(devc,4)|0x8080);
......@@ -203,7 +199,7 @@ static void ad1816_halt_output (int dev)
outb ((unsigned char)~0x80, devc->base+1);
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,
......@@ -217,14 +213,13 @@ static void ad1816_output_block (int dev, unsigned long buf,
cnt = count/4 - 1;
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
/* set transfer count */
ad_write (devc, 8, cnt & 0xffff);
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,
cnt = count/4 - 1;
save_flags (flags); /* make register access atomic */
cli ();
spin_lock_irqsave(&devc->lock,flags);
/* set transfer count */
ad_write (devc, 10, cnt & 0xffff);
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)
......@@ -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));
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
fmt_bits= (devc->format_bits&0x7)<<3;
......@@ -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, 3, freq & 0xffff);
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_input(dev);
return 0;
......@@ -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));
save_flags (flags); /* make register access atomic */
cli ();
spin_lock_irqsave(&devc->lock,flags);
fmt_bits= (devc->format_bits&0x7)<<3;
/* set mono/stereo mode */
......@@ -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, 3, freq & 0xffff);
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_output(dev);
return 0;
......@@ -351,8 +343,7 @@ static void ad1816_trigger (int dev, int state)
/* mode may have changed */
save_flags (flags); /* make register access atomic */
cli ();
spin_lock_irqsave(&devc->lock,flags);
/* mask out modes not specified on open call */
state &= devc->audio_mode;
......@@ -377,7 +368,7 @@ static void ad1816_trigger (int dev, int state)
/* disable capture */
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)
devc = (ad1816_info *) audio_devs[dev]->devc;
/* make check if device already open atomic */
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
if (devc->opened) {
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -(EBUSY);
}
......@@ -497,7 +487,7 @@ static int ad1816_open (int dev, int mode)
devc->channels=1;
ad1816_reset(devc->dev_no); /* halt all pending output */
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
......@@ -506,8 +496,7 @@ static void ad1816_close (int dev) /* close device */
unsigned long flags;
ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
/* halt all pending output */
ad1816_reset(devc->dev_no);
......@@ -518,8 +507,7 @@ static void ad1816_close (int dev) /* close device */
devc->audio_format=AFMT_U8;
devc->format_bits = 0;
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
......@@ -556,7 +544,6 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
unsigned char status;
ad1816_info *devc;
int dev;
unsigned long flags;
if (irq < 0 || irq > 15) {
......@@ -574,8 +561,7 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
devc = (ad1816_info *) audio_devs[dev]->devc;
save_flags(flags);
cli();
spin_lock(&devc->lock);
/* read interrupt register */
status = inb (devc->base+1);
......@@ -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))
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 )
devc->irq = 0;
devc->opened = 0;
devc->osp = osp;
spin_lock_init(&devc->lock);
/* base+0: bit 1 must be set but not 255 */
tmp=inb(devc->base);
......
......@@ -47,6 +47,7 @@
#include <linux/stddef.h>
#include <linux/pm.h>
#include <linux/isapnp.h>
#include <linux/spinlock.h>
#define DEB(x)
#define DEB1(x)
......@@ -57,6 +58,7 @@
typedef struct
{
spinlock_t lock;
int base;
int irq;
int dma1, dma2;
......@@ -212,8 +214,7 @@ static int ad_read(ad1848_info * devc, int reg)
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if(reg < 32)
{
......@@ -230,7 +231,7 @@ static int ad_read(ad1848_info * devc, int reg)
outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
x = inb(io_Indexed_Data(devc));
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return x;
}
......@@ -243,8 +244,7 @@ static void ad_write(ad1848_info * devc, int reg, int data)
while (timeout > 0 && inb(devc->base) == 0x80) /* Are we initializing */
timeout--;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if(reg < 32)
{
......@@ -261,7 +261,7 @@ static void ad_write(ad1848_info * devc, int reg, int data)
outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
outb((unsigned char) (data & 0xff), io_Indexed_Data(devc));
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void wait_for_calibration(ad1848_info * devc)
......@@ -324,18 +324,17 @@ static void ad_enter_MCE(ad1848_info * devc)
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
devc->MCE_bit = 0x40;
prev = inb(io_Index_Addr(devc));
if (prev & 0x40)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
outb((devc->MCE_bit), io_Index_Addr(devc));
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad_leave_MCE(ad1848_info * devc)
......@@ -347,8 +346,7 @@ static void ad_leave_MCE(ad1848_info * devc)
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
acal = ad_read(devc, 9);
......@@ -358,13 +356,13 @@ static void ad_leave_MCE(ad1848_info * devc)
if ((prev & 0x40) == 0) /* Not in MCE mode */
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */
if (acal & 0x08) /* Auto calibration is enabled */
wait_for_calibration(devc);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static int ad1848_set_recmask(ad1848_info * devc, int mask)
......@@ -975,7 +973,7 @@ static struct mixer_operations ad1848_mixer_operations =
static int ad1848_open(int dev, int mode)
{
ad1848_info *devc = NULL;
ad1848_info *devc;
ad1848_port_info *portc;
unsigned long flags;
......@@ -985,11 +983,10 @@ static int ad1848_open(int dev, int mode)
devc = (ad1848_info *) audio_devs[dev]->devc;
portc = (ad1848_port_info *) audio_devs[dev]->portc;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (portc->open_mode || (devc->open_mode & mode))
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -EBUSY;
}
devc->dual_dma = 0;
......@@ -1008,7 +1005,7 @@ static int ad1848_open(int dev, int mode)
devc->record_dev = dev;
if (mode & OPEN_WRITE)
devc->playback_dev = dev;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
/*
* Mute output until the playback really starts. This decreases clicking (hope so).
*/
......@@ -1025,8 +1022,7 @@ static void ad1848_close(int dev)
DEB(printk("ad1848_close(void)\n"));
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
devc->intr_active = 0;
ad1848_halt(dev);
......@@ -1036,7 +1032,7 @@ static void ad1848_close(int dev)
portc->open_mode = 0;
ad_unmute(devc);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
......@@ -1070,8 +1066,7 @@ static void ad1848_output_block(int dev, unsigned long buf, int count, int intrf
* Auto DMA mode on. No need to react
*/
}
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_write(devc, 15, (unsigned char) (cnt & 0xff));
ad_write(devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
......@@ -1079,7 +1074,7 @@ static void ad1848_output_block(int dev, unsigned long buf, int count, int intrf
devc->xfer_count = cnt;
devc->audio_mode |= PCM_ENABLE_OUTPUT;
devc->intr_active = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
......@@ -1112,8 +1107,7 @@ static void ad1848_start_input(int dev, unsigned long buf, int count, int intrfl
* Auto DMA mode on. No need to react
*/
}
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (devc->model == MD_1848)
{
......@@ -1131,7 +1125,7 @@ static void ad1848_start_input(int dev, unsigned long buf, int count, int intrfl
devc->xfer_count = cnt;
devc->audio_mode |= PCM_ENABLE_INPUT;
devc->intr_active = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
......@@ -1144,8 +1138,7 @@ static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
ad_mute(devc);
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
fs = portc->speed_bits | (portc->format_bits << 5);
if (portc->channels > 1)
......@@ -1189,7 +1182,7 @@ static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
ad_leave_MCE(devc); /*
* Starts the calibration process.
*/
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
devc->xfer_count = 0;
#ifndef EXCLUDE_TIMERS
......@@ -1214,8 +1207,7 @@ static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
if (devc->audio_mode)
return 0;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
fs = portc->speed_bits | (portc->format_bits << 5);
if (portc->channels > 1)
......@@ -1303,7 +1295,7 @@ static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
ad_leave_MCE(devc); /*
* Starts the calibration process.
*/
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
devc->xfer_count = 0;
#ifndef EXCLUDE_TIMERS
......@@ -1342,8 +1334,7 @@ static void ad1848_halt_input(int dev)
if (!(ad_read(devc, 9) & 0x02))
return; /* Capture not enabled */
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_mute(devc);
......@@ -1368,7 +1359,7 @@ static void ad1848_halt_input(int dev)
devc->audio_mode &= ~PCM_ENABLE_INPUT;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_halt_output(int dev)
......@@ -1379,8 +1370,7 @@ static void ad1848_halt_output(int dev)
if (!(ad_read(devc, 9) & 0x01))
return; /* Playback not enabled */
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_mute(devc);
{
......@@ -1405,7 +1395,7 @@ static void ad1848_halt_output(int dev)
devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_trigger(int dev, int state)
......@@ -1415,8 +1405,7 @@ static void ad1848_trigger(int dev, int state)
unsigned long flags;
unsigned char tmp, old;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
state &= devc->audio_mode;
tmp = old = ad_read(devc, 9);
......@@ -1441,7 +1430,7 @@ static void ad1848_trigger(int dev, int state)
ad_write(devc, 9, tmp);
ad_unmute(devc);
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_init_hw(ad1848_info * devc)
......@@ -1978,6 +1967,7 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback,
ad1848_port_info *portc = NULL;
spin_lock_init(&devc->lock);
devc->irq = (irq > 0) ? irq : 0;
devc->open_mode = 0;
devc->timer_ticks = 0;
......@@ -2245,10 +2235,8 @@ void adintr(int irq, void *dev_id, struct pt_regs *dummy)
{
if (devc->model == MD_C930)
{ /* 82C930 has interrupt status register in MAD16 register MC11 */
unsigned long flags;
save_flags(flags);
cli();
spin_lock(&devc->lock);
/* 0xe0e is C930 address port
* 0xe0f is C930 data port
......@@ -2257,7 +2245,7 @@ void adintr(int irq, void *dev_id, struct pt_regs *dummy)
c930_stat = inb(0xe0f);
outb((~c930_stat), 0xe0f);
restore_flags(flags);
spin_unlock(&devc->lock);
alt_stat = (c930_stat << 2) & 0x30;
}
......@@ -2733,8 +2721,7 @@ static unsigned int ad1848_tmr_start(int dev, unsigned int usecs)
unsigned long xtal_nsecs; /* nanoseconds per xtal oscillator tick */
unsigned long divider;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
/*
* Length of the timer interval (in nanoseconds) depends on the
......@@ -2766,7 +2753,7 @@ static unsigned int ad1848_tmr_start(int dev, unsigned int usecs)
ad_write(devc, 20, divider & 0xff); /* Set lower bits */
ad_write(devc, 16, ad_read(devc, 16) | 0x40); /* Start the timer */
devc->timer_running = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return current_interval = (divider * xtal_nsecs + 500) / 1000;
}
......@@ -2787,11 +2774,10 @@ static void ad1848_tmr_disable(int dev)
unsigned long flags;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_write(devc, 16, ad_read(devc, 16) & ~0x40);
devc->timer_running = 0;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1848_tmr_restart(int dev)
......@@ -2802,11 +2788,10 @@ static void ad1848_tmr_restart(int dev)
if (current_interval == 0)
return;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_write(devc, 16, ad_read(devc, 16) | 0x40);
devc->timer_running = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static struct sound_lowlev_timer ad1848_tmr =
......@@ -2834,12 +2819,11 @@ static int ad1848_suspend(ad1848_info *devc)
{
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ad_mute(devc);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
......@@ -2848,8 +2832,7 @@ static int ad1848_resume(ad1848_info *devc)
unsigned long flags;
int mixer_levels[32], i;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
/* Thinkpad is a bit more of PITA than normal. The BIOS tends to
restore it in a different config to the one we use. Need to
......@@ -2875,7 +2858,7 @@ static int ad1848_resume(ad1848_info *devc)
bits = interrupt_bits[devc->irq];
if (bits == -1) {
printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -1;
}
......@@ -2890,8 +2873,8 @@ static int ad1848_resume(ad1848_info *devc)
outb((bits | dma_bits[devc->dma1] | dma2_bit), config_port);
}
restore_flags(flags);
return 0;
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
static int ad1848_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
......
......@@ -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)
{
/*
* This just allows interrupts while the conversion is running
*/
sti();
translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
}
c -= used;
......@@ -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)
{
/*
* This just allows interrupts while the conversion is running
*/
sti();
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)
break;
}
save_flags (flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
/* Compute number of bytes that have been played */
count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
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)
count = dmap->user_counter - count;
if (count < 0)
count = 0;
restore_flags (flags);
spin_unlock_irqrestore(&dmap->lock,flags);
val = count;
break;
......@@ -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) &&
(bits & PCM_ENABLE_OUTPUT))
return -EINVAL;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
changed = audio_devs[dev]->enable_bits ^ bits;
if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
{
reorganize_buffers(dev, dmap_in, 1);
if ((err = audio_devs[dev]->d->prepare_for_input(dev,
dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return -err;
}
dmap_in->dma_mode = DMODE_INPUT;
......@@ -867,7 +856,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
if (changed && audio_devs[dev]->d->trigger)
audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
#endif
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
/* Falls through... */
case SNDCTL_DSP_GETTRIGGER:
......@@ -884,8 +873,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
case SNDCTL_DSP_GETIPTR:
if (!(audio_devs[dev]->open_mode & OPEN_READ))
return -EINVAL;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
cinfo.bytes = dmap_in->byte_counter;
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
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)
cinfo.bytes += cinfo.ptr;
if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
dmap_in->qlen = 0; /* Reset interrupt counter */
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
......@@ -903,8 +891,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
return -EINVAL;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
cinfo.bytes = dmap_out->byte_counter;
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
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)
cinfo.bytes += cinfo.ptr;
if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
dmap_out->qlen = 0; /* Reset interrupt counter */
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
......@@ -926,8 +913,7 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
ret=0;
break;
}
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
/* Compute number of bytes that have been played */
count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
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)
count = dmap_out->user_counter - count;
if (count < 0)
count = 0;
restore_flags (flags);
spin_unlock_irqrestore(&dmap->lock,flags);
ret = count;
break;
......
......@@ -199,6 +199,7 @@ static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffpar
return -EBUSY;
}
dma_init_buffers(dmap);
spin_lock_init(&dmap->lock);
dmap->open_mode = mode;
dmap->subdivision = dmap->underrun_count = 0;
dmap->fragment_size = 0;
......@@ -319,7 +320,7 @@ int DMAbuf_open(int dev, int mode)
adev->dmap_out->bytes_in_use);
return 0;
}
/* MUST not hold the spinlock */
void DMAbuf_reset(int dev)
{
if (audio_devs[dev]->open_mode & OPEN_WRITE)
......@@ -341,15 +342,17 @@ static void dma_reset_output(int dev)
/*
* First wait until the current fragment has been played completely
*/
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
adev->dmap_out->flags |= DMA_SYNCING;
adev->dmap_out->underrun_count = 0;
if (!signal_pending(current) && adev->dmap_out->qlen &&
adev->dmap_out->underrun_count == 0)
adev->dmap_out->underrun_count == 0){
spin_unlock_irqrestore(&dmap->lock,flags);
interruptible_sleep_on_timeout(&adev->out_sleeper,
dmabuf_timeout(dmap));
spin_lock_irqsave(&dmap->lock,flags);
}
adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
/*
......@@ -366,10 +369,10 @@ static void dma_reset_output(int dev)
disable_dma(dmap->dma);
release_dma_lock(f);
restore_flags(flags);
dmap->byte_counter = 0;
reorganize_buffers(dev, adev->dmap_out, 0);
dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
spin_unlock_irqrestore(&dmap->lock,flags);
}
static void dma_reset_input(int dev)
......@@ -378,20 +381,19 @@ static void dma_reset_input(int dev)
unsigned long flags;
struct dma_buffparms *dmap = adev->dmap_in;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_input)
adev->d->halt_io(dev);
else
adev->d->halt_input(dev);
adev->dmap_in->flags &= ~DMA_STARTED;
restore_flags(flags);
dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
dmap->byte_counter = 0;
reorganize_buffers(dev, adev->dmap_in, 1);
spin_unlock_irqrestore(&dmap->lock,flags);
}
/* MUST be called with holding the dmap->lock */
void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -432,8 +434,7 @@ int DMAbuf_sync(int dev)
if (adev->dmap_out->dma_mode == DMODE_OUTPUT) {
dmap = adev->dmap_out;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
if (dmap->qlen > 0 && !(dmap->flags & DMA_ACTIVE))
DMAbuf_launch_output(dev, dmap);
adev->dmap_out->flags |= DMA_SYNCING;
......@@ -441,31 +442,33 @@ int DMAbuf_sync(int dev)
while (!signal_pending(current) && n++ <= adev->dmap_out->nbufs &&
adev->dmap_out->qlen && adev->dmap_out->underrun_count == 0) {
long t = dmabuf_timeout(dmap);
t = interruptible_sleep_on_timeout(&adev->out_sleeper,
t);
spin_unlock_irqrestore(&dmap->lock,flags);
t = interruptible_sleep_on_timeout(&adev->out_sleeper, t);
spin_lock_irqsave(&dmap->lock,flags);
if (!t) {
adev->dmap_out->flags &= ~DMA_SYNCING;
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return adev->dmap_out->qlen;
}
}
adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
restore_flags(flags);
/*
* Some devices such as GUS have huge amount of on board RAM for the
* audio data. We have to wait until the device has finished playing.
*/
save_flags(flags);
cli();
/* still holding the lock */
if (adev->d->local_qlen) { /* Device has hidden buffers */
while (!signal_pending(current) &&
adev->d->local_qlen(dev))
adev->d->local_qlen(dev)){
spin_unlock_irqrestore(&dmap->lock,flags);
interruptible_sleep_on_timeout(&adev->out_sleeper,
dmabuf_timeout(dmap));
spin_lock_irqsave(&dmap->lock,flags);
}
}
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
}
adev->dmap_out->dma_mode = DMODE_NONE;
return adev->dmap_out->qlen;
......@@ -474,23 +477,26 @@ int DMAbuf_sync(int dev)
int DMAbuf_release(int dev, int mode)
{
struct audio_operations *adev = audio_devs[dev];
struct dma_buffparms *dmap;
unsigned long flags;
dmap = adev->dmap_out;
if (adev->open_mode & OPEN_WRITE)
adev->dmap_out->closing = 1;
if (adev->open_mode & OPEN_READ)
adev->dmap_in->closing = 1;
if (adev->open_mode & OPEN_READ){
adev->dmap_in->closing = 1;
dmap = adev->dmap_in;
}
if (adev->open_mode & OPEN_WRITE)
if (!(adev->dmap_out->mapping_flags & DMA_MAP_MAPPED))
if (!signal_pending(current) && (adev->dmap_out->dma_mode == DMODE_OUTPUT))
DMAbuf_sync(dev);
if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte, adev->dmap_out->bytes_in_use);
save_flags(flags);
cli();
DMAbuf_reset(dev);
spin_lock_irqsave(&dmap->lock,flags);
adev->d->close(dev);
if (adev->open_mode & OPEN_WRITE)
......@@ -501,10 +507,10 @@ int DMAbuf_release(int dev, int mode)
(adev->flags & DMA_DUPLEX)))
close_dmap(adev, adev->dmap_in);
adev->open_mode = 0;
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return 0;
}
/* called with dmap->lock dold */
int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -515,8 +521,12 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
if (!(adev->enable_bits & PCM_ENABLE_INPUT))
return 0;
if (dmap->dma_mode == DMODE_OUTPUT) { /* Direction change */
unsigned long flags;
/* release lock - it's not recursive */
spin_unlock_irqrestore(&dmap->lock,flags);
DMAbuf_sync(dev);
DMAbuf_reset(dev);
spin_lock_irqsave(&dmap->lock,flags);
dmap->dma_mode = DMODE_NONE;
}
if (!dmap->dma_mode) {
......@@ -538,7 +548,7 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
}
return 0;
}
/* aquires lock */
int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -549,34 +559,36 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
if (!(adev->open_mode & OPEN_READ))
return -EIO;
spin_lock_irqsave(&dmap->lock,flags);
if (dmap->needs_reorg)
reorganize_buffers(dev, dmap, 0);
save_flags(flags);
cli();
if (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) {
/* printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return -EINVAL;
} else while (dmap->qlen <= 0 && n++ < 10) {
long timeout = MAX_SCHEDULE_TIMEOUT;
if (!(adev->enable_bits & PCM_ENABLE_INPUT) || !adev->go) {
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return -EAGAIN;
}
if ((err = DMAbuf_activate_recording(dev, dmap)) < 0) {
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return err;
}
/* Wait for the next block */
if (dontblock) {
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return -EAGAIN;
}
if ((go = adev->go))
timeout = dmabuf_timeout(dmap);
spin_unlock_irqrestore(&dmap->lock,flags);
timeout = interruptible_sleep_on_timeout(&adev->in_sleeper,
timeout);
spin_lock_irqsave(&dmap->lock,flags);
if (!timeout) {
/* FIXME: include device name */
err = -EIO;
......@@ -585,7 +597,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
} else
err = -EINTR;
}
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
if (dmap->qlen <= 0)
return err ? err : -EINTR;
......@@ -617,7 +629,7 @@ int DMAbuf_rmchars(int dev, int buff_no, int c)
return 0;
}
/* MUST be called with dmap->lock hold */
int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
{
/*
......@@ -626,11 +638,8 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
*/
int pos;
unsigned long flags;
unsigned long f;
save_flags(flags);
cli();
if (!(dmap->flags & DMA_ACTIVE))
pos = 0;
else {
......@@ -667,7 +676,6 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
release_dma_lock(f);
}
restore_flags(flags);
/* printk( "%04x ", pos); */
return pos;
......@@ -698,7 +706,7 @@ void DMAbuf_start_devices(unsigned int devmask)
adev->d->trigger(dev,adev->enable_bits * adev->go);
}
}
/* via poll called without a lock ?*/
int DMAbuf_space_in_queue(int dev)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -735,7 +743,7 @@ int DMAbuf_space_in_queue(int dev)
return 0;
return max - len;
}
/* MUST not hold the spinlock - this function may sleep */
static int output_sleep(int dev, int dontblock)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -770,12 +778,11 @@ static int output_sleep(int dev, int dontblock)
}
return err;
}
/* called with the lock held */
static int find_output_space(int dev, char **buf, int *size)
{
struct audio_operations *adev = audio_devs[dev];
struct dma_buffparms *dmap = adev->dmap_out;
unsigned long flags;
unsigned long active_offs;
long len, offs;
int maxfrags;
......@@ -784,8 +791,6 @@ static int find_output_space(int dev, char **buf, int *size)
*buf = dmap->raw_buf;
if (!(maxfrags = DMAbuf_space_in_queue(dev)) && !occupied_bytes)
return 0;
save_flags(flags);
cli();
#ifdef BE_CONSERVATIVE
active_offs = dmap->byte_counter + dmap->qhead * dmap->fragment_size;
......@@ -799,7 +804,6 @@ static int find_output_space(int dev, char **buf, int *size)
offs = (dmap->user_counter % dmap->bytes_in_use) & ~SAMPLE_ROUNDUP;
if (offs < 0 || offs >= dmap->bytes_in_use) {
restore_flags(flags);
printk(KERN_ERR "Sound: Got unexpected offs %ld. Giving up.\n", offs);
printk("Counter = %ld, bytes=%d\n", dmap->user_counter, dmap->bytes_in_use);
return 0;
......@@ -811,16 +815,14 @@ static int find_output_space(int dev, char **buf, int *size)
if ((offs + len) > dmap->bytes_in_use)
len = dmap->bytes_in_use - offs;
if (len < 0) {
restore_flags(flags);
return 0;
}
if (len > ((maxfrags * dmap->fragment_size) - occupied_bytes))
len = (maxfrags * dmap->fragment_size) - occupied_bytes;
*size = len & ~SAMPLE_ROUNDUP;
restore_flags(flags);
return (*size > 0);
}
/* aquires lock */
int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -828,39 +830,45 @@ int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
int err = -EIO;
struct dma_buffparms *dmap = adev->dmap_out;
if (dmap->needs_reorg)
reorganize_buffers(dev, dmap, 0);
if (dmap->mapping_flags & DMA_MAP_MAPPED) {
/* printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
return -EINVAL;
}
spin_lock_irqsave(&dmap->lock,flags);
if (dmap->needs_reorg)
reorganize_buffers(dev, dmap, 0);
if (dmap->dma_mode == DMODE_INPUT) { /* Direction change */
spin_unlock_irqrestore(&dmap->lock,flags);
DMAbuf_reset(dev);
dmap->dma_mode = DMODE_NONE;
spin_lock_irqsave(&dmap->lock,flags);
}
dmap->dma_mode = DMODE_OUTPUT;
save_flags(flags);
cli();
while (find_output_space(dev, buf, size) <= 0) {
spin_unlock_irqrestore(&dmap->lock,flags);
if ((err = output_sleep(dev, dontblock)) < 0) {
restore_flags(flags);
return err;
}
spin_lock_irqsave(&dmap->lock,flags);
}
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
return 0;
}
/* has to aquire dmap->lock */
int DMAbuf_move_wrpointer(int dev, int l)
{
struct audio_operations *adev = audio_devs[dev];
struct dma_buffparms *dmap = adev->dmap_out;
unsigned long ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
unsigned long ptr;
unsigned long end_ptr, p;
int post = (dmap->flags & DMA_POST);
int post;
unsigned long flags;
spin_lock_irqsave(&dmap->lock,flags);
post= (dmap->flags & DMA_POST);
ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
dmap->flags &= ~DMA_POST;
dmap->cfrag = -1;
......@@ -890,7 +898,7 @@ int DMAbuf_move_wrpointer(int dev, int l)
dmap->counts[dmap->qtail] = dmap->user_counter - ptr;
/*
* Let the low level driver to perform some postprocessing to
* Let the low level driver perform some postprocessing to
* the written data.
*/
if (adev->d->postprocess_write)
......@@ -899,6 +907,8 @@ int DMAbuf_move_wrpointer(int dev, int l)
if (!(dmap->flags & DMA_ACTIVE))
if (dmap->qlen > 1 || (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))
DMAbuf_launch_output(dev, dmap);
spin_unlock_irqrestore(&dmap->lock,flags);
return 0;
}
......@@ -945,11 +955,10 @@ static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
wake_up(&adev->out_sleeper);
wake_up(&adev->poll_sleeper);
}
/* called with dmap->lock held in irq context*/
static void do_outputintr(int dev, int dummy)
{
struct audio_operations *adev = audio_devs[dev];
unsigned long flags;
struct dma_buffparms *dmap = adev->dmap_out;
int this_fragment;
......@@ -977,8 +986,6 @@ static void do_outputintr(int dev, int dummy)
finish_output_interrupt(dev, dmap);
return;
}
save_flags(flags);
cli();
dmap->qlen--;
this_fragment = dmap->qhead;
......@@ -1014,18 +1021,16 @@ static void do_outputintr(int dev, int dummy)
}
if (dmap->qlen > 0)
DMAbuf_launch_output(dev, dmap);
restore_flags(flags);
finish_output_interrupt(dev, dmap);
}
/* called in irq context */
void DMAbuf_outputintr(int dev, int notify_only)
{
struct audio_operations *adev = audio_devs[dev];
unsigned long flags;
struct dma_buffparms *dmap = adev->dmap_out;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
if (!(dmap->flags & DMA_NODMA)) {
int chan = dmap->dma, pos, n;
unsigned long f;
......@@ -1049,9 +1054,9 @@ void DMAbuf_outputintr(int dev, int notify_only)
}
else
do_outputintr(dev, notify_only);
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
}
/* called with dmap->lock held in irq context */
static void do_inputintr(int dev)
{
struct audio_operations *adev = audio_devs[dev];
......@@ -1117,15 +1122,14 @@ static void do_inputintr(int dev)
wake_up(&adev->poll_sleeper);
}
}
/* called in irq context */
void DMAbuf_inputintr(int dev)
{
struct audio_operations *adev = audio_devs[dev];
struct dma_buffparms *dmap = adev->dmap_in;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
if (!(dmap->flags & DMA_NODMA)) {
int chan = dmap->dma, pos, n;
......@@ -1149,7 +1153,7 @@ void DMAbuf_inputintr(int dev)
do_inputintr(dev);
} else
do_inputintr(dev);
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
}
int DMAbuf_open_dma(int dev)
......@@ -1240,10 +1244,9 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
!dmap->qlen && adev->go) {
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&dmap->lock,flags);
DMAbuf_activate_recording(dev, dmap);
restore_flags(flags);
spin_unlock_irqrestore(&dmap->lock,flags);
}
return 0;
}
......
......@@ -199,8 +199,11 @@ struct m3_state {
int index;
/* this locks around the oss state in the driver */
spinlock_t lock;
/* no, this lock is removed - only use card->lock */
/* otherwise: against what are you protecting on SMP
when irqhandler uses s->lock
and m3_assp_read uses card->lock ?
*/
struct semaphore open_sem;
wait_queue_head_t open_wait;
mode_t open_mode;
......@@ -1066,8 +1069,6 @@ u32 get_dmac(struct m3_state *s)
}
static void m3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int
prog_dmabuf(struct m3_state *s, unsigned rec)
{
......@@ -1078,7 +1079,7 @@ prog_dmabuf(struct m3_state *s, unsigned rec)
unsigned char fmt;
unsigned long flags;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
fmt = s->fmt;
if (rec) {
......@@ -1126,7 +1127,7 @@ prog_dmabuf(struct m3_state *s, unsigned rec)
db->ready = 1;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
return 0;
}
......@@ -1250,9 +1251,9 @@ static void m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if(ctl & DSP2HOST_REQ_TIMER) {
outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS);
/* update adc/dac info if it was a timer int */
spin_lock(&s->lock);
spin_lock(&c->lock);
m3_update_ptr(s);
spin_unlock(&s->lock);
spin_unlock(&c->lock);
}
}
}
......@@ -1292,9 +1293,9 @@ static int drain_dac(struct m3_state *s, int nonblock)
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&s->dma_dac.wait, &wait);
for (;;) {
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
count = s->dma_dac.count;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
if (count <= 0)
break;
if (signal_pending(current))
......@@ -1337,7 +1338,7 @@ static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *pp
return -EFAULT;
ret = 0;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
while (count > 0) {
int timed_out;
......@@ -1358,9 +1359,9 @@ static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *pp
goto out;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
if(timed_out) {
printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
......@@ -1378,12 +1379,12 @@ static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *pp
continue;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
ret = ret ? ret : -EFAULT;
return ret;
}
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
swptr = (swptr + cnt) % s->dma_adc.dmasize;
s->dma_adc.swptr = swptr;
......@@ -1395,7 +1396,7 @@ static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *pp
}
out:
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
return ret;
}
......@@ -1418,7 +1419,7 @@ static ssize_t m3_write(struct file *file, const char *buffer, size_t count, lof
return -EFAULT;
ret = 0;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
while (count > 0) {
int timed_out;
......@@ -1444,9 +1445,9 @@ static ssize_t m3_write(struct file *file, const char *buffer, size_t count, lof
if(!ret) ret = -EAGAIN;
goto out;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
if(timed_out) {
DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
......@@ -1461,12 +1462,12 @@ static ssize_t m3_write(struct file *file, const char *buffer, size_t count, lof
}
continue;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
if (!ret) ret = -EFAULT;
return ret;
}
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",
cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);
......@@ -1482,7 +1483,7 @@ static ssize_t m3_write(struct file *file, const char *buffer, size_t count, lof
start_dac(s);
}
out:
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
return ret;
}
......@@ -1498,7 +1499,7 @@ static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
if (file->f_mode & FMODE_READ)
poll_wait(file, &s->dma_adc.wait, wait);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&s->card->lock, flags);
m3_update_ptr(s);
if (file->f_mode & FMODE_READ) {
......@@ -1515,7 +1516,7 @@ static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
}
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&s->card->lock, flags);
return mask;
}
......@@ -1572,6 +1573,7 @@ static int m3_mmap(struct file *file, struct vm_area_struct *vma)
static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct m3_state *s = (struct m3_state *)file->private_data;
struct m3_card *card=s->card;
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
......@@ -1602,23 +1604,23 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
case SNDCTL_DSP_RESET:
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
synchronize_irq();
synchronize_irq(s->card->pcidev->irq);
s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
}
if (file->f_mode & FMODE_READ) {
stop_adc(s);
synchronize_irq();
synchronize_irq(s->card->pcidev->irq);
s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return 0;
case SNDCTL_DSP_SPEED:
get_user_ret(val, (int *)arg, -EFAULT);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
stop_adc(s);
......@@ -1631,12 +1633,12 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
set_dac_rate(s, val);
}
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
case SNDCTL_DSP_STEREO:
get_user_ret(val, (int *)arg, -EFAULT);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
fmtd = 0;
fmtm = ~0;
if (file->f_mode & FMODE_READ) {
......@@ -1656,12 +1658,12 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
}
set_fmt(s, fmtm, fmtd);
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return 0;
case SNDCTL_DSP_CHANNELS:
get_user_ret(val, (int *)arg, -EFAULT);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (val != 0) {
fmtd = 0;
fmtm = ~0;
......@@ -1683,7 +1685,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
}
set_fmt(s, fmtm, fmtd);
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)
: (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
......@@ -1692,7 +1694,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
get_user_ret(val, (int *)arg, -EFAULT);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (val != AFMT_QUERY) {
fmtd = 0;
fmtm = ~0;
......@@ -1714,7 +1716,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
}
set_fmt(s, fmtm, fmtd);
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ?
(ESS_FMT_16BIT << ESS_ADC_SHIFT)
: (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ?
......@@ -1758,13 +1760,13 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
return -EINVAL;
if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
return val;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
m3_update_ptr(s);
abinfo.fragsize = s->dma_dac.fragsize;
abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
......@@ -1772,13 +1774,13 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
return -EINVAL;
if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
return val;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
m3_update_ptr(s);
abinfo.fragsize = s->dma_adc.fragsize;
abinfo.bytes = s->dma_adc.count;
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
......@@ -1788,23 +1790,23 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
case SNDCTL_DSP_GETODELAY:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
m3_update_ptr(s);
val = s->dma_dac.count;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return put_user(val, (int *)arg);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
m3_update_ptr(s);
cinfo.bytes = s->dma_adc.total_bytes;
cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
cinfo.ptr = s->dma_adc.hwptr;
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
......@@ -1812,14 +1814,14 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
m3_update_ptr(s);
cinfo.bytes = s->dma_dac.total_bytes;
cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
cinfo.ptr = s->dma_dac.hwptr;
if (s->dma_dac.mapped)
s->dma_dac.count &= s->dma_dac.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
......@@ -1836,7 +1838,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
case SNDCTL_DSP_SETFRAGMENT:
get_user_ret(val, (int *)arg, -EFAULT);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
......@@ -1857,7 +1859,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
if (s->dma_dac.ossmaxfrags < 4)
s->dma_dac.ossmaxfrags = 4;
}
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
return 0;
case SNDCTL_DSP_SUBDIVIDE:
......@@ -2019,7 +2021,7 @@ static int m3_open(struct inode *inode, struct file *file)
down(&s->open_sem);
}
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&c->lock, flags);
if (file->f_mode & FMODE_READ) {
fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
......@@ -2041,13 +2043,14 @@ static int m3_open(struct inode *inode, struct file *file)
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&c->lock, flags);
return 0;
}
static int m3_release(struct inode *inode, struct file *file)
{
struct m3_state *s = (struct m3_state *)file->private_data;
struct m3_card *card=s->card;
unsigned long flags;
VALIDATE_STATE(s);
......@@ -2055,7 +2058,7 @@ static int m3_release(struct inode *inode, struct file *file)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
spin_lock_irqsave(&s->lock, flags);
spin_lock_irqsave(&card->lock, flags);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
......@@ -2074,7 +2077,7 @@ static int m3_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
spin_unlock_irqrestore(&s->lock, flags);
spin_unlock_irqrestore(&card->lock, flags);
up(&s->open_sem);
wake_up(&s->open_wait);
......@@ -2666,7 +2669,6 @@ static int __init m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
spin_lock_init(&s->lock);
init_MUTEX(&(s->open_sem));
s->magic = M3_STATE_MAGIC;
......@@ -2777,8 +2779,7 @@ static int m3_suspend(struct pci_dev *pci_dev, u32 state)
struct m3_card *card = pci_get_drvdata(pci_dev);
/* must be a better way.. */
save_flags(flags);
cli();
spin_lock_irqsave(&card->lock, flags);
DPRINTK(DPMOD, "pm in dev %p\n",card);
......@@ -2816,7 +2817,7 @@ static int m3_suspend(struct pci_dev *pci_dev, u32 state)
card->in_suspend = 1;
restore_flags(flags);
spin_unlock_irqrestore(&card->lock, flags);
return 0;
}
......@@ -2828,8 +2829,7 @@ static int m3_resume(struct pci_dev *pci_dev)
int i;
struct m3_card *card = pci_get_drvdata(pci_dev);
save_flags(flags); /* paranoia */
cli();
spin_lock_irqsave(&card->lock, flags);
card->in_suspend = 0;
DPRINTK(DPMOD, "resuming\n");
......@@ -2892,7 +2892,7 @@ static int m3_resume(struct pci_dev *pci_dev)
start_adc(s);
}
restore_flags(flags);
spin_unlock_irqrestore(&card->lock, flags);
/*
* all right, we think things are ready,
......
......@@ -15,7 +15,7 @@
*/
#include <linux/stddef.h>
#include <linux/kmod.h>
#include <linux/spinlock.h>
#define MIDIBUF_C
#include "sound_config.h"
......@@ -55,6 +55,7 @@ static struct timer_list poll_timer = {
};
static volatile int open_devs = 0;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
#define DATA_AVAIL(q) (q->len)
#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
......@@ -63,20 +64,20 @@ static volatile int open_devs = 0;
if (SPACE_AVAIL(q)) \
{ \
unsigned long flags; \
save_flags( flags);cli(); \
spin_lock_irqsave(&lock, flags); \
q->queue[q->tail] = (data); \
q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
restore_flags(flags); \
spin_unlock_irqrestore(&lock, flags); \
}
#define REMOVE_BYTE(q, data) \
if (DATA_AVAIL(q)) \
{ \
unsigned long flags; \
save_flags( flags);cli(); \
spin_lock_irqsave(&lock, flags); \
data = q->queue[q->head]; \
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)
......@@ -122,8 +123,7 @@ static void midi_poll(unsigned long dummy)
unsigned long flags;
int dev;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (open_devs)
{
for (dev = 0; dev < num_midis; dev++)
......@@ -135,9 +135,9 @@ static void midi_poll(unsigned long dummy)
{
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);
cli();
spin_lock_irqsave(&lock, flags);
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
midi_out_buf[dev]->len--;
}
......@@ -151,7 +151,7 @@ static void midi_poll(unsigned long dummy)
* Come back later
*/
}
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
}
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)
{
int mode;
unsigned long flags;
dev = dev >> 4;
mode = translate_mode(file);
......@@ -225,9 +224,6 @@ void MIDIbuf_release(int dev, struct file *file)
if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
return;
save_flags(flags);
cli();
/*
* Wait until the queue is empty
*/
......@@ -249,7 +245,6 @@ void MIDIbuf_release(int dev, struct file *file)
* Ensure the output queues are empty
*/
}
restore_flags(flags);
midi_devs[dev]->close(dev);
......@@ -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)
{
unsigned long flags;
int c, n, i;
unsigned char tmp_data;
......@@ -276,9 +270,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
if (!count)
return 0;
save_flags(flags);
cli();
c = 0;
while (c < count)
......@@ -308,6 +299,8 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
for (i = 0; i < n; i++)
{
/* 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)) {
c = -EFAULT;
goto out;
......@@ -317,7 +310,6 @@ int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
}
}
out:
restore_flags(flags);
return c;
}
......@@ -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 n, c = 0;
unsigned long flags;
unsigned char tmp_data;
dev = dev >> 4;
save_flags(flags);
cli();
if (!DATA_AVAIL(midi_in_buf[dev])) { /*
* No data yet, wait
*/
......@@ -361,6 +349,8 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
REMOVE_BYTE(midi_in_buf[dev], tmp_data);
fixit = (char *) &tmp_data;
/* 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)) {
c = -EFAULT;
goto out;
......@@ -369,7 +359,6 @@ int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
}
}
out:
restore_flags(flags);
return c;
}
......@@ -440,7 +429,7 @@ void MIDIbuf_init(void)
int MIDIbuf_avail(int dev)
{
if (midi_in_buf[dev])
if (midi_in_buf[dev])
return DATA_AVAIL (midi_in_buf[dev]);
return 0;
}
......@@ -19,7 +19,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#define USE_SEQ_MACROS
#define USE_SIMPLE_MACROS
......@@ -68,6 +68,7 @@ struct mpu_config
void (*inputintr) (int dev, unsigned char data);
int shared_irq;
int *osp;
spinlock_t lock;
};
#define DATAPORT(base) (base)
......@@ -408,11 +409,10 @@ static void mpu401_input_loop(struct mpu_config *devc)
int busy;
int n;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
busy = devc->m_busy;
devc->m_busy = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
if (busy) /* Already inside the scanner */
return;
......@@ -447,7 +447,6 @@ void mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
struct mpu_config *devc;
int dev = (int) dev_id;
sti();
devc = &dev_conf[dev];
if (input_avail(devc))
......@@ -559,16 +558,15 @@ static int mpu401_out(int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (!output_ready(devc))
{
printk(KERN_WARNING "mpu401: Send data timeout\n");
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
write_data(devc, midi_byte);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 1;
}
......@@ -606,13 +604,12 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd);
return -EIO;
}
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (!output_ready(devc))
{
restore_flags(flags);
goto retry;
spin_unlock_irqrestore(&devc->lock,flags);
goto retry;
}
write_command(devc, cmd->cmd);
......@@ -636,7 +633,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
}
if (!ok)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -EIO;
}
if (cmd->nr_args)
......@@ -647,7 +644,7 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
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);
return -EIO;
}
......@@ -669,12 +666,12 @@ static int mpu401_command(int dev, mpu_command_rec * cmd)
}
if (!ok)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -EIO;
}
}
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return ret;
}
......@@ -941,16 +938,15 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
devc->version = devc->revision = 0;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
devc->version = tmp;
......@@ -958,11 +954,11 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0)
{
devc->version = 0;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
devc->revision = tmp;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
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->shared_irq = hw_config->always_detect;
devc->irq = hw_config->irq;
spin_lock_init(&devc->lock);
if (devc->irq < 0)
{
......@@ -1020,12 +1017,11 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
return;
}
}
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
mpu401_chk_version(m, devc);
if (devc->version == 0)
mpu401_chk_version(m, devc);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
request_region(hw_config->io_base, 2, "mpu401");
......@@ -1154,12 +1150,11 @@ static int reset_mpu401(struct mpu_config *devc)
for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
{
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (input_avail(devc))
if (read_data(devc) == MPU_ACK)
ok = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
}
......@@ -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;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
next_event_time = (unsigned long) -1;
prev_event_time = 0;
curr_ticks = curr_clocks = 0;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static void set_timer_mode(int midi_dev)
......@@ -1353,7 +1347,9 @@ static void setup_metronome(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);
if (tmr_running)
......@@ -1378,11 +1374,12 @@ static int mpu_start_timer(int midi_dev)
static int mpu_timer_open(int dev, int mode)
{
int midi_dev = sound_timer_devs[dev]->devlink;
struct mpu_config *devc= &dev_conf[midi_dev];
if (timer_open)
return -EBUSY;
tmr_reset();
tmr_reset(devc);
curr_tempo = 50;
mpu_cmd(midi_dev, 0xE0, 50);
curr_timebase = hw_timebase = 120;
......
......@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "nm256.h"
#include "nm256_coeff.h"
......@@ -262,8 +263,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
return;
}
save_flags (flags);
cli ();
spin_lock_irqsave(&card->lock,flags);
/*
* If we're not currently recording, set up the start and end registers
* for the recording engine.
......@@ -283,7 +283,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
}
else {
/* Not sure what else to do here. */
restore_flags (flags);
spin_unlock_irqrestore(&card->lock,flags);
return;
}
}
......@@ -303,7 +303,7 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG,
NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);
restore_flags (flags);
spin_unlock_irqrestore(&card->lock,flags);
}
/* Stop the play engine. */
......@@ -370,8 +370,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt)
card->requested_amt = amt;
save_flags (flags);
cli ();
spin_lock_irqsave(&card->lock,flags);
if ((card->curPlayPos + amt) >= ringsize) {
u32 rem = ringsize - card->curPlayPos;
......@@ -418,7 +417,7 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt)
if (! card->playing)
startPlay (card);
restore_flags (flags);
spin_unlock_irqrestore(&card->lock,flags);
}
/* We just got a card playback interrupt; process it. */
......@@ -829,8 +828,7 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value)
base = card->mixer;
save_flags (flags);
cli ();
spin_lock_irqsave(&card->lock,flags);
nm256_isReady (dev);
......@@ -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);
return ! done;
......@@ -1055,6 +1053,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr)
card->playing = 0;
card->recording = 0;
card->rev = rev;
spin_lock_init(&card->lock);
/* Init the memory port info. */
for (x = 0; x < 2; x++) {
......
......@@ -14,10 +14,13 @@
*/
#include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "pas2.h"
extern spinlock_t lock;
static int midi_busy = 0, input_opened = 0;
static int my_dev;
......@@ -48,12 +51,11 @@ static int pas_midi_open(int dev, int mode,
pas_write(0x20 | 0x40,
0x178b);
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if ((err = pas_set_intr(0x10)) < 0)
{
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
return err;
}
/*
......@@ -81,7 +83,7 @@ static int pas_midi_open(int dev, int mode,
pas_write(0xff, 0x1B88);
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
midi_busy = 1;
qlen = qhead = qtail = 0;
......@@ -131,8 +133,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
* Drain the local queue first
*/
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
while (qlen && dump_to_midi(tmp_queue[qhead]))
{
......@@ -140,7 +141,7 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
qhead++;
}
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
/*
* Output the byte if the local queue is empty.
......@@ -157,14 +158,13 @@ static int pas_midi_out(int dev, unsigned char midi_byte)
if (qlen >= 256)
return 0; /* Local queue full */
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
tmp_queue[qtail] = midi_byte;
qlen++;
qtail++;
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
return 1;
}
......@@ -226,7 +226,6 @@ void pas_midi_interrupt(void)
{
unsigned char stat;
int i, incount;
unsigned long flags;
stat = pas_read(0x1B88);
......@@ -245,8 +244,7 @@ void pas_midi_interrupt(void)
}
if (stat & (0x08 | 0x10))
{
save_flags(flags);
cli();
spin_lock(&lock);/* called in irq context */
while (qlen && dump_to_midi(tmp_queue[qhead]))
{
......@@ -254,7 +252,7 @@ void pas_midi_interrupt(void)
qhead++;
}
restore_flags(flags);
spin_unlock(&lock);
}
if (stat & 0x40)
{
......
......@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "pas2.h"
......@@ -44,6 +45,8 @@ static int pcm_busy = 0;
int pas_audiodev = -1;
static int open_mode = 0;
extern spinlock_t lock;
static int pcm_set_speed(int arg)
{
int foo, tmp;
......@@ -101,8 +104,7 @@ static int pcm_set_speed(int arg)
pcm_filter = tmp;
#endif
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
pas_write(0x00 | 0x30 | 0x04, 0x138B);
......@@ -110,7 +112,7 @@ static int pcm_set_speed(int arg)
pas_write((foo >> 8) & 0xff, 0x1388);
pas_write(tmp, 0x0B8A);
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
return pcm_speed;
}
......@@ -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));
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (pcm_busy)
{
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
return -EBUSY;
}
pcm_busy = 1;
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
return err;
......@@ -238,15 +239,14 @@ static void pas_audio_close(int dev)
DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
pas_audio_reset(dev);
pas_remove_intr(PAS_PCM_INTRBITS);
pcm_mode = PCM_NON;
pcm_busy = 0;
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
}
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)
return;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
pas_write(pas_read(0xF8A) & ~0x40,
0xF8A);
......@@ -293,7 +292,7 @@ static void pas_audio_output_block(int dev, unsigned long buf, int count,
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,
......@@ -313,8 +312,7 @@ static void pas_audio_start_input(int dev, unsigned long buf, int count,
cnt == pcm_count)
return;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
/* 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,
pcm_mode = PCM_ADC;
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
}
#ifndef NO_TRIGGER
......@@ -346,8 +344,7 @@ static void pas_audio_trigger(int dev, int state)
{
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
state &= open_mode;
if (state & PCM_ENABLE_OUTPUT)
......@@ -357,7 +354,7 @@ static void pas_audio_trigger(int dev, int state)
else
pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
restore_flags(flags);
spin_unlock_irqrestore(&lock, flags);
}
#endif
......
......@@ -60,6 +60,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "sound_firmware.h"
......@@ -142,6 +143,7 @@ typedef struct pss_confdata {
static pss_confdata pss_data;
static pss_confdata *devc = &pss_data;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
static int pss_initialized = 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
return -EFAULT;
}
data = (unsigned short *)(mbuf->data);
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
for (i = 0; i < mbuf->len; i++) {
if (!pss_put_dspword(devc, *data++)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
mbuf->len = i; /* feed back number of WORDs sent */
err = copy_to_user(arg, mbuf, sizeof(copr_msg));
vfree(mbuf);
return err ? -EFAULT : -EIO;
}
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
vfree(mbuf);
return 0;
......@@ -859,8 +860,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
if (mbuf == NULL)
return -ENOSPC;
data = (unsigned short *)mbuf->data;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
mbuf->len = i; /* feed back number of WORDs read */
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
break;
}
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
err = -EFAULT;
vfree(mbuf);
......@@ -878,22 +878,21 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
case SNDCTL_COPR_RDATA:
if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (!pss_put_dspword(devc, 0x00d0)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_get_dspword(devc, &tmp)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
dbuf.parm1 = tmp;
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
return -EFAULT;
return 0;
......@@ -901,74 +900,71 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
case SNDCTL_COPR_WDATA:
if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (!pss_put_dspword(devc, 0x00d1)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
tmp = (unsigned int)dbuf.parm2 & 0xffff;
if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return 0;
case SNDCTL_COPR_WCODE:
if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (!pss_put_dspword(devc, 0x00d3)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
tmp = (unsigned int)dbuf.parm2 & 0x00ff;
if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
if (!pss_put_dspword(devc, tmp)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return 0;
case SNDCTL_COPR_RCODE:
if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
return -EFAULT;
save_flags(flags);
cli();
spin_lock_irqsave(&lock, flags);
if (!pss_put_dspword(devc, 0x00d2)) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
dbuf.parm1 = tmp << 8;
if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return -EIO;
}
dbuf.parm1 |= tmp & 0x00ff;
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
return -EFAULT;
return 0;
......
......@@ -15,7 +15,7 @@
* Alan Cox : reformatted and fixed a pair of null pointer bugs
*/
#include <linux/kmod.h>
#include <linux/spinlock.h>
#define SEQUENCER_C
#include "sound_config.h"
......@@ -28,6 +28,7 @@ static int pending_timer = -1; /* For timer change operation */
extern unsigned long seq_time;
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
......@@ -95,37 +96,38 @@ int sequencer_read(int dev, struct file *file, char *buf, int count)
ev_len = seq_mode == SEQ_1 ? 4 : 8;
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
if (!iqlen)
{
spin_unlock_irqrestore(&lock,flags);
if (file->f_flags & O_NONBLOCK) {
restore_flags(flags);
return -EAGAIN;
}
interruptible_sleep_on_timeout(&midi_sleeper,
pre_event_timeout);
spin_lock_irqsave(&lock,flags);
if (!iqlen)
{
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return 0;
}
}
while (iqlen && c >= ev_len)
{
char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
spin_unlock_irqrestore(&lock,flags);
if (copy_to_user(&(buf)[p], fixit, ev_len))
goto out;
return count - c;
p += ev_len;
c -= ev_len;
spin_lock_irqsave(&lock,flags);
iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
iqlen--;
}
out:
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return count - c;
}
......@@ -152,13 +154,12 @@ void seq_copy_to_input(unsigned char *event_rec, int len)
if (iqlen >= (SEQ_MAX_QUEUE - 1))
return; /* Overflow */
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len);
iqlen++;
iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
wake_up(&midi_sleeper);
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
}
static void sequencer_midi_input(int dev, unsigned char data)
......@@ -869,19 +870,19 @@ static int play_event(unsigned char *q)
return 0;
}
/* called also as timer in irq context */
static void seq_startplay(void)
{
unsigned long flags;
int this_one, action;
unsigned long flags;
while (qlen > 0)
{
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
qlen--;
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
seq_playing = 1;
......@@ -947,7 +948,6 @@ int sequencer_open(int dev, struct file *file)
{
int retval, mode, i;
int level, tmp;
unsigned long flags;
if (!sequencer_ok)
sequencer_init();
......@@ -979,16 +979,12 @@ int sequencer_open(int dev, struct file *file)
return -ENXIO;
}
}
save_flags(flags);
cli();
if (sequencer_busy)
{
restore_flags(flags);
return -EBUSY;
}
sequencer_busy = 1;
obsolete_api_used = 0;
restore_flags(flags);
max_mididev = num_midis;
max_synthdev = num_synths;
......@@ -1203,16 +1199,11 @@ void sequencer_release(int dev, struct file *file)
static int seq_sync(void)
{
unsigned long flags;
if (qlen && !seq_playing && !signal_pending(current))
seq_startplay();
save_flags(flags);
cli();
if (qlen > 0)
interruptible_sleep_on_timeout(&seq_sleeper, HZ);
restore_flags(flags);
return qlen;
}
......@@ -1233,13 +1224,12 @@ static void midi_outc(int dev, unsigned char data)
n = 3 * HZ; /* Timeout */
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
while (n && !midi_devs[dev]->outputc(dev, data)) {
interruptible_sleep_on_timeout(&seq_sleeper, HZ/25);
n--;
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
}
static void seq_reset(void)
......@@ -1308,14 +1298,13 @@ static void seq_reset(void)
seq_playing = 0;
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
if (waitqueue_active(&seq_sleeper)) {
/* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
wake_up(&seq_sleeper);
}
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
}
static void seq_panic(void)
......@@ -1499,10 +1488,9 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
case SNDCTL_SEQ_OUTOFBAND:
if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
return -EFAULT;
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
play_event(event_rec.arr);
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return 0;
case SNDCTL_MIDI_INFO:
......@@ -1554,8 +1542,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
dev = dev >> 4;
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
/* input */
poll_wait(file, &midi_sleeper, wait);
if (iqlen)
......@@ -1565,7 +1552,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
poll_wait(file, &seq_sleeper, wait);
if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
mask |= POLLOUT | POLLWRNORM;
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
return mask;
}
......
......@@ -40,6 +40,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/wrapper.h>
#include <linux/spinlock.h>
#include "coproc.h"
......@@ -115,7 +116,7 @@ typedef struct sscape_info
char* raw_buf;
unsigned long raw_buf_phys;
int buffsize; /* -------------------------- */
spinlock_t lock;
int ok; /* Properly detected */
int failed;
int dma_allocated;
......@@ -164,11 +165,10 @@ static unsigned char sscape_read(struct sscape_info *devc, int reg)
unsigned long flags;
unsigned char val;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
outb(reg, PORT(ODIE_ADDR));
val = inb(PORT(ODIE_DATA));
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return val;
}
......@@ -176,11 +176,10 @@ static void sscape_write(struct sscape_info *devc, int reg, int data)
{
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
outb(reg, PORT(ODIE_ADDR));
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)
......@@ -188,11 +187,10 @@ static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
unsigned char res;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
outb( reg, devc -> codec);
res = inb (devc -> codec + 1);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return res;
}
......@@ -201,11 +199,10 @@ static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigne
{
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
outb( reg, devc -> codec);
outb( data, devc -> codec + 1);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
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)
unsigned long flags;
int i, timeout_val;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
/*
* Send the command and data bytes
*/
......@@ -238,12 +233,12 @@ static int host_write(struct sscape_info *devc, unsigned char *data, int count)
if (timeout_val <= 0)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
outb(data[i], PORT(HOST_DATA));
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 1;
}
......@@ -253,9 +248,7 @@ static int host_read(struct sscape_info *devc)
int timeout_val;
unsigned char data;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
/*
* Read a byte
*/
......@@ -266,11 +259,11 @@ static int host_read(struct sscape_info *devc)
if (timeout_val <= 0)
{
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -1;
}
data = inb(PORT(HOST_DATA));
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return data;
}
......@@ -391,14 +384,13 @@ static void sscape_coproc_close(void *dev_info, int sub_device)
struct sscape_info *devc = dev_info;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (devc->dma_allocated)
{
sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
devc->dma_allocated = 0;
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return;
}
......@@ -420,14 +412,13 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
* before continuing.
*/
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
if (devc->dma_allocated == 0)
devc->dma_allocated = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
sscape_write(devc, GA_HMCTL_REG,
(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,
}
memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
/******** INTERRUPTS DISABLED NOW ********/
......@@ -475,7 +465,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
done = 1;
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
if (!done)
return 0;
......@@ -494,9 +484,7 @@ static int sscape_download_boot(struct sscape_info *devc, unsigned char *block,
/*
* Wait until the ODB wakes up
*/
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
done = 0;
timeout_val = 5 * HZ;
while (!done && timeout_val-- > 0)
......@@ -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);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
if (!done)
{
printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
return 0;
}
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
done = 0;
timeout_val = 5 * HZ;
while (!done && timeout_val-- > 0)
......@@ -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 */
done = 1;
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
if (!done)
{
printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
......@@ -675,8 +662,7 @@ void __init attach_sscape(struct address_info *hw_config)
if (!sscape_is_pnp) {
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
for (i = 1; i < 10; i++)
{
switch (i)
......@@ -710,7 +696,7 @@ void __init attach_sscape(struct address_info *hw_config)
sscape_write(devc, i, regs[i]);
}
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
#ifdef SSCAPE_DEBUG2
/*
......@@ -960,8 +946,7 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
return 0;
}
dt = data;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
while ( len > 0 ) {
if (len > devc -> buffsize) l = devc->buffsize;
else l = len;
......@@ -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_pnp_start_dma ( devc, 0 );
if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
}
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
vfree(data);
outb(0, devc -> base + 2);
......@@ -1469,6 +1454,7 @@ static int __init init_sscape(void)
devc->codec_type = 0;
devc->ic_type = 0;
devc->raw_buf = NULL;
spin_lock_init(&devc->lock);
if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
......
......@@ -23,7 +23,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "mpu401.h"
......@@ -38,6 +38,7 @@ typedef struct uart401_devc
volatile unsigned char input_byte;
int my_dev;
int share_irq;
spinlock_t lock;
}
uart401_devc;
......@@ -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.
*/
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (input_avail(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
......@@ -222,8 +221,7 @@ static void enter_uart_mode(uart401_devc * devc)
int ok, timeout;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
devc->input_byte = 0;
......@@ -237,7 +235,7 @@ static void enter_uart_mode(uart401_devc * devc)
if (uart401_read(devc) == MPU_ACK)
ok = 1;
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
}
static int reset_uart401(uart401_devc * devc)
......@@ -320,11 +318,11 @@ int probe_uart401(struct address_info *hw_config, struct module *owner)
devc->input_byte = 0;
devc->my_dev = 0;
devc->share_irq = 0;
spin_lock_init(&devc->lock);
save_flags(flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
ok = reset_uart401(devc);
restore_flags(flags);
spin_unlock_irqrestore(&devc->lock,flags);
if (!ok)
goto cleanup_devc;
......
......@@ -23,7 +23,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
* added 6850 support, used with COVOX SoundMaster II and custom cards.
*/
......@@ -71,6 +71,7 @@ static int uart6850_opened;
static int uart6850_irq;
static int uart6850_detected;
static int my_dev;
static spinlock_t lock=SPIN_LOCK_UNLOCKED;
static void (*midi_input_intr) (int dev, unsigned char data);
static void poll_uart6850(unsigned long dummy);
......@@ -122,9 +123,7 @@ static void poll_uart6850(unsigned long dummy)
if (!(uart6850_opened & OPEN_READ))
return; /* Device has been closed */
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
if (input_avail())
uart6850_input_loop();
......@@ -135,7 +134,7 @@ static void poll_uart6850(unsigned long dummy)
* Come back later
*/
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
}
static int uart6850_open(int dev, int mode,
......@@ -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.
*/
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
if (input_avail())
uart6850_input_loop();
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
/*
* 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)
uart6850_osp = hw_config->osp;
uart6850_irq = hw_config->irq;
save_flags(flags);
cli();
spin_lock_irqsave(&lock,flags);
for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /*
* Wait
*/
uart6850_cmd(UART_MODE_ON);
ok = 1;
restore_flags(flags);
spin_unlock_irqrestore(&lock,flags);
conf_printf("6850 Midi Interface", hw_config);
......
......@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "v_midi.h"
......@@ -52,15 +52,14 @@ static int v_midi_open (int dev, int mode,
if (devc == NULL)
return -(ENXIO);
save_flags (flags);
cli();
spin_lock_irqsave(&devc->lock,flags);
if (devc->opened)
{
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
return -(EBUSY);
}
devc->opened = 1;
restore_flags (flags);
spin_unlock_irqrestore(&devc->lock,flags);
devc->intr_active = 1;
......@@ -81,12 +80,11 @@ static void v_midi_close (int dev)
if (devc == NULL)
return;
save_flags (flags);
cli ();
spin_lock_irqsave(&devc->lock,flags);
devc->intr_active = 0;
devc->input_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)
......@@ -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]->intr_active = 0;
v_devc[0]->midi_input_intr = NULL;
spin_lock_init(&v_devc[0]->lock);
midi_devs[midi1]->devc = v_devc[0];
......@@ -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]->intr_active = 0;
v_devc[1]->midi_input_intr = NULL;
spin_lock_init(&v_devc[1]->lock);
midi_devs[midi2]->devc = v_devc[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