--- drivers/sound/maestro3.c.old Tue May 8 22:24:57 2001 +++ drivers/sound/maestro3.c Wed Jun 6 00:00:06 2001 @@ -242,6 +242,7 @@ dma_addr_t handle; } dma_dac, dma_adc; + struct semaphore sem; }; struct m3_card { @@ -1328,7 +1329,7 @@ static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct m3_state *s = (struct m3_state *)file->private_data; - ssize_t ret; + ssize_t ret = 0; unsigned long flags; unsigned swptr; int cnt; @@ -1338,12 +1339,11 @@ return -ESPIPE; if (s->dma_adc.mapped) return -ENXIO; - if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) - return ret; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - ret = 0; - + down(&s->sem); + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + goto out; spin_lock_irqsave(&s->lock, flags); while (count > 0) { @@ -1361,10 +1361,10 @@ start_adc(s); if (file->f_flags & O_NONBLOCK) { - ret = ret ? ret : -EAGAIN; + if(!ret) ret = -EAGAIN; goto out; } - + up(&s->sem); spin_unlock_irqrestore(&s->lock, flags); timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0; spin_lock_irqsave(&s->lock, flags); @@ -1379,16 +1379,22 @@ } if (signal_pending(current)) { - ret = ret ? ret : -ERESTARTSYS; + if(!ret) ret = -ERESTARTSYS; goto out; } + down(&s->sem); + if (s->dma_adc.mapped) + { + ret = -ENXIO; + goto out; + } continue; } spin_unlock_irqrestore(&s->lock, flags); if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { - ret = ret ? ret : -EFAULT; - return ret; + if(!ret) ret = -EFAULT; + goto out; } spin_lock_irqsave(&s->lock, flags); @@ -1402,6 +1408,7 @@ } out: + up(&s->sem); spin_unlock_irqrestore(&s->lock, flags); return ret; } @@ -1419,10 +1426,11 @@ return -ESPIPE; if (s->dma_dac.mapped) return -ENXIO; - if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) - return ret; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + down(&s->sem); + if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) + goto out; ret = 0; spin_lock_irqsave(&s->lock, flags); @@ -1451,6 +1459,7 @@ if(!ret) ret = -EAGAIN; goto out; } + up(&s->sem); spin_unlock_irqrestore(&s->lock, flags); timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0; spin_lock_irqsave(&s->lock, flags); @@ -1466,12 +1475,18 @@ if (!ret) ret = -ERESTARTSYS; goto out; } + down(&s->sem); + if (s->dma_dac.mapped) + { + ret = -ENXIO; + goto out; + } continue; } spin_unlock_irqrestore(&s->lock, flags); if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { if (!ret) ret = -EFAULT; - return ret; + goto out; } spin_lock_irqsave(&s->lock, flags); @@ -1489,6 +1504,7 @@ start_dac(s); } out: + up(&s->sem); spin_unlock_irqrestore(&s->lock, flags); return ret; } @@ -1534,17 +1550,20 @@ int ret = -EINVAL; VALIDATE_STATE(s); + down(&s->sem); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(s, 0)) != 0) - return ret; + goto out; db = &s->dma_dac; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(s, 1)) != 0) - return ret; + goto out; db = &s->dma_adc; - } else - return -EINVAL; + } else { + ret = -EINVAL; + goto out; + } max_size = db->dmasize; @@ -1554,14 +1573,17 @@ if(size > max_size) goto out; + if(offset > max_size - size) + { + ret = -EAGAIN; goto out; + } /* * this will be ->nopage() once I can * ask Jeff what the hell I'm doing wrong. */ - ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) goto out; @@ -1569,6 +1591,7 @@ ret = 0; out: + up(&s->sem); return ret; } @@ -2674,6 +2697,7 @@ init_waitqueue_head(&s->open_wait); spin_lock_init(&s->lock); init_MUTEX(&(s->open_sem)); + init_MUTEX(&s->sem); s->magic = M3_STATE_MAGIC; m3_assp_client_init(s);