--- drivers/sound/maestro.c.old Tue Jun 5 21:21:43 2001 +++ drivers/sound/maestro.c Tue Jun 5 23:44:41 2001 @@ -431,6 +431,7 @@ /* pointer to each dsp?s piece of the apu->src buffer page */ void *mixbuf; + struct semaphore sem; }; @@ -2258,7 +2259,7 @@ ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct ess_state *s = (struct ess_state *)file->private_data; - ssize_t ret; + ssize_t ret = 0; unsigned long flags; unsigned swptr; int cnt; @@ -2269,13 +2270,13 @@ 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; if(!(combbuf = kmalloc(count,GFP_KERNEL))) return -ENOMEM; - ret = 0; + down(&s->sem); + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + goto rec_return_free; calc_bob_rate(s); @@ -2298,9 +2299,10 @@ start_adc(s); if (file->f_flags & O_NONBLOCK) { - ret = ret ? ret : -EAGAIN; + if(!ret) ret = -EAGAIN; goto rec_return_free; } + up(&s->sem); if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, @@ -2317,7 +2319,13 @@ } if (signal_pending(current)) { - ret = ret ? ret : -ERESTARTSYS; + if(!ret) ret = -ERESTARTSYS; + goto rec_return_free; + } + down(&s->sem); + if (s->dma_adc.mapped) + { + ret = -ENXIO; goto rec_return_free; } continue; @@ -2327,12 +2335,12 @@ /* swptr/2 so that we know the real offset in each apu's buffer */ comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize); if (copy_to_user(buffer, combbuf, cnt)) { - ret = ret ? ret : -EFAULT; + if(!ret) ret = -EFAULT; goto rec_return_free; } } else { if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { - ret = ret ? ret : -EFAULT; + if(!ret) ret = -EFAULT; goto rec_return_free; } } @@ -2349,6 +2357,7 @@ } rec_return_free: + up(&s->sem); if(combbuf) kfree(combbuf); return ret; } @@ -2367,10 +2376,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 return_free; ret = 0; calc_bob_rate(s); @@ -2400,6 +2410,7 @@ if(!ret) ret = -EAGAIN; goto return_free; } + up(&s->sem); if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) { if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, @@ -2418,6 +2429,12 @@ if (!ret) ret = -ERESTARTSYS; goto return_free; } + down(&s->sem); + if (s->dma_dac.mapped) + { + ret = -ENXIO; + goto return_free; + } continue; } if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { @@ -2439,6 +2456,7 @@ start_dac(s); } return_free: + up(&s->sem); return ret; } @@ -2493,11 +2511,12 @@ VALIDATE_STATE(s); lock_kernel(); + down(&s->sem); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(s, 1)) != 0) goto out; db = &s->dma_dac; - } else + } else { #if 0 /* if we can have the wp/wc do the combining we can turn this back on. */ @@ -2507,19 +2526,23 @@ db = &s->dma_adc; } else #endif + ret = -EINVAL; goto out; - ret = -EINVAL; + } if (vma->vm_pgoff != 0) goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) + { + ret = -EAGAIN; goto out; - ret = -EAGAIN; + } if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) goto out; db->mapped = 1; ret = 0; out: + up(&s->sem); unlock_kernel(); return ret; } @@ -3463,6 +3486,7 @@ init_waitqueue_head(&s->open_wait); spin_lock_init(&s->lock); init_MUTEX(&s->open_sem); + init_MUTEX(&s->sem); s->magic = ESS_STATE_MAGIC; s->apu[0] = 6*i;