* sound driver locking patches
@ 2001-06-12 23:22 Frank Davis
0 siblings, 0 replies; only message in thread
From: Frank Davis @ 2001-06-12 23:22 UTC (permalink / raw)
To: linux-kernel; +Cc: fdavis112
[-- Attachment #1: Type: TEXT/PLAIN, Size: 269 bytes --]
Hello all,
I have attached sound driver locking patches for:
drivers/sound/cs4281/cs4281m.c
drivers/sound/i810_audio.c
The patches are against 2.4.5-ac13, and address the sound driver locking
issue mentioned in the -ac series.
Please review. Thanks.
Regards,
Frank
[-- Attachment #2: Type: TEXT/PLAIN, Size: 5061 bytes --]
--- drivers/sound/cs4281/cs4281m.c.old Mon Jun 11 00:23:02 2001
+++ drivers/sound/cs4281/cs4281m.c Tue Jun 12 01:17:14 2001
@@ -293,6 +293,7 @@
struct cs4281_pm pm;
struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
+ struct semaphore sem;
};
#include "cs4281pm-24.c"
@@ -2876,7 +2877,7 @@
{
struct cs4281_state *s =
(struct cs4281_state *) file->private_data;
- ssize_t ret;
+ ssize_t ret = 0;
unsigned long flags;
unsigned swptr;
int cnt;
@@ -2890,11 +2891,12 @@
return -ESPIPE;
if (s->dma_adc.mapped)
return -ENXIO;
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- return ret;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- ret = 0;
+
+ down(&s->sem);
+ if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+ goto out;
//
// "count" is the amount of bytes to read (from app), is decremented each loop
// by the amount of bytes that have been returned to the user buffer.
@@ -2950,10 +2952,23 @@
// the loop when wake up occurs.
start_adc(s);
if (file->f_flags & O_NONBLOCK)
- return ret ? ret : -EAGAIN;
+ {
+ if(!ret) ret = -EAGAIN;
+ goto out;
+ }
+ up(&s->sem);
interruptible_sleep_on(&s->dma_adc.wait);
if (signal_pending(current))
- return ret ? ret : -ERESTARTSYS;
+ {
+ if(!ret) ret = -ERESTARTSYS;
+ goto out;
+ }
+ down(&s->sem);
+ if (s->dma_adc.mapped)
+ {
+ ret = -ENXIO;
+ goto out;
+ }
continue;
}
// there are bytes in the buffer to read.
@@ -2971,7 +2986,10 @@
if (cs_copy_to_user
(s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
- return ret ? ret : -EFAULT;
+ {
+ if(!ret) ret = -EFAULT;
+ goto out;
+ }
swptr = (swptr + cnt) % s->dma_adc.dmasize;
spin_lock_irqsave(&s->lock, flags);
s->dma_adc.swptr = swptr;
@@ -2984,6 +3002,8 @@
}
CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
printk(KERN_INFO "cs4281: cs4281_read()- %d\n", ret));
+out:
+ up(&s->sem);
return ret;
}
@@ -3007,10 +3027,12 @@
return -ESPIPE;
if (s->dma_dac.mapped)
return -ENXIO;
- if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
- return ret;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
+ down(&s->sem);
+ if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+ goto out;
+
ret = 0;
while (count > 0) {
spin_lock_irqsave(&s->lock, flags);
@@ -3035,14 +3057,30 @@
if (cnt <= 0) {
start_dac(s);
if (file->f_flags & O_NONBLOCK)
- return ret ? ret : -EAGAIN;
+ {
+ if(!ret) ret = -EAGAIN;
+ goto out;
+ }
+ up(&s->sem);
interruptible_sleep_on(&s->dma_dac.wait);
if (signal_pending(current))
- return ret ? ret : -ERESTARTSYS;
+ {
+ if(!ret) ret = -ERESTARTSYS;
+ goto out;
+ }
+ down(&s->sem);
+ if (s->dma_dac.mapped)
+ {
+ ret = -ENXIO;
+ goto out;
+ }
continue;
}
if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
- return ret ? ret : -EFAULT;
+ {
+ if(!ret) ret = -EFAULT;
+ goto out;
+ }
swptr = (swptr + cnt) % s->dma_dac.dmasize;
spin_lock_irqsave(&s->lock, flags);
s->dma_dac.swptr = swptr;
@@ -3056,6 +3094,8 @@
}
CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
printk(KERN_INFO "cs4281: cs4281_write()- %d\n", ret));
+out:
+ up(&s->sem);
return ret;
}
@@ -3132,35 +3172,49 @@
printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
VALIDATE_STATE(s);
+ down(&s->sem);
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_dac(s)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf_adc(s)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
- } else
- return -EINVAL;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
//
// only support PLAYBACK for now
//
db = &s->dma_dac;
if (cs4x_pgoff(vma) != 0)
- return -EINVAL;
+ {
+ ret = -EINVAL;
+ goto out;
+ }
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ {
+ ret = -EINVAL;
+ goto out;
+ }
if (remap_page_range
(vma->vm_start, virt_to_phys(db->rawbuf), size,
- vma->vm_page_prot)) return -EAGAIN;
+ vma->vm_page_prot))
+ {
+ ret = -EAGAIN;
+ goto out;
+ }
db->mapped = 1;
CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
(unsigned) size));
-
+out:
+ up(&s->sem);
return 0;
}
@@ -4323,6 +4377,7 @@
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
init_MUTEX(&s->open_sem);
+ init_MUTEX(&s->sem);
init_MUTEX(&s->open_sem_adc);
init_MUTEX(&s->open_sem_dac);
spin_lock_init(&s->lock);
[-- Attachment #3: Type: TEXT/PLAIN, Size: 3920 bytes --]
--- drivers/sound/i810_audio.c.old Mon Jun 11 00:23:05 2001
+++ drivers/sound/i810_audio.c Tue Jun 12 19:03:50 2001
@@ -298,6 +298,7 @@
unsigned ossmaxfrags;
unsigned subdivision;
} dmabuf;
+ struct semaphore sem;
};
@@ -1066,7 +1067,7 @@
{
struct i810_state *state = (struct i810_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
- ssize_t ret;
+ ssize_t ret = 0;
unsigned long flags;
unsigned int swptr;
int cnt;
@@ -1088,13 +1089,14 @@
return -EBUSY;
}
}
- if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
- return ret;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
dmabuf->trigger &= ~PCM_ENABLE_OUTPUT;
- ret = 0;
+ down(&state->sem);
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+ goto out;
+
while (count > 0) {
spin_lock_irqsave(&state->card->lock, flags);
swptr = dmabuf->swptr;
@@ -1119,8 +1121,9 @@
}
if (file->f_flags & O_NONBLOCK) {
if (!ret) ret = -EAGAIN;
- return ret;
+ goto out;
}
+ up(&state->sem);
/* This isnt strictly right for the 810 but it'll do */
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
tmo >>= 1;
@@ -1142,15 +1145,21 @@
while loop begin and we REALLY have space to record */
}
if (signal_pending(current)) {
- ret = ret ? ret : -ERESTARTSYS;
- return ret;
+ if(!ret) ret = -ERESTARTSYS;
+ goto out;
+ }
+ down(&state->sem);
+ if (dmabuf->mapped)
+ {
+ ret = -ENXIO;
+ goto out;
}
continue;
}
if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
if (!ret) ret = -EFAULT;
- return ret;
+ goto out;
}
swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1164,6 +1173,8 @@
buffer += cnt;
ret += cnt;
}
+out:
+ up(&state->sem);
i810_update_lvi(state,1);
start_adc(state);
return ret;
@@ -1196,11 +1207,12 @@
if(!dmabuf->write_channel)
return -EBUSY;
}
- if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
- return ret;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
dmabuf->trigger &= ~PCM_ENABLE_INPUT;
+ down(&state->sem);
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
+ goto out;
ret = 0;
while (count > 0) {
@@ -1228,8 +1240,9 @@
}
if (file->f_flags & O_NONBLOCK) {
if (!ret) ret = -EAGAIN;
- return ret;
+ goto out;
}
+ up(&state->sem);
/* Not strictly correct but works */
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 4);
/* There are two situations when sleep_on_timeout returns, one is when
@@ -1252,13 +1265,19 @@
}
if (signal_pending(current)) {
if (!ret) ret = -ERESTARTSYS;
- return ret;
+ goto out;
}
continue;
}
+ down(&state->sem);
+ if (dmabuf->mapped)
+ {
+ ret = -ENXIO;
+ goto out;
+ }
if (copy_from_user(dmabuf->rawbuf+swptr,buffer,cnt)) {
if (!ret) ret = -EFAULT;
- return ret;
+ goto out;
}
swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1277,6 +1296,8 @@
if((x + dmabuf->count) < dmabuf->dmasize)
memset(dmabuf->rawbuf + swptr, '\0', x);
}
+out:
+ up(&state->sem);
i810_update_lvi(state,0);
if (!dmabuf->enable && dmabuf->count >= dmabuf->userfragsize)
start_dac(state);
@@ -1323,6 +1344,7 @@
unsigned long size;
lock_kernel();
+ down(&state->sem);
if (vma->vm_flags & VM_WRITE) {
if (!dmabuf->write_channel &&
(dmabuf->write_channel =
@@ -1362,6 +1384,7 @@
printk("i810_audio: mmap'ed %ld bytes of data space\n", size);
#endif
out:
+ up(&state->sem);
unlock_kernel();
return ret;
}
@@ -1784,6 +1807,7 @@
state->magic = I810_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
init_MUTEX(&state->open_sem);
+ init_MUTEX(&state->sem);
file->private_data = state;
dmabuf->trigger = 0;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2001-06-12 23:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-12 23:22 sound driver locking patches Frank Davis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).