--- drivers/sound/esssolo1.c.old Tue Jun 5 01:34:16 2001 +++ drivers/sound/esssolo1.c Tue Jun 5 01:48:00 2001 @@ -226,6 +226,7 @@ } midi; struct gameport gameport; + struct semaphore sem; }; /* --------------------------------------------------------------------- */ @@ -1010,7 +1011,7 @@ { struct solo1_state *s = (struct solo1_state *)file->private_data; DECLARE_WAITQUEUE(wait, current); - ssize_t ret; + ssize_t ret = 0; unsigned long flags; unsigned swptr; int cnt; @@ -1020,11 +1021,13 @@ 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; + add_wait_queue(&s->dma_adc.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); @@ -1058,8 +1061,9 @@ if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; - break; + goto out; } + up(&s->sem); schedule(); #ifdef DEBUGREC printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" @@ -1073,14 +1077,20 @@ if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; - break; + goto out; + } + down(&s->sem); + if (s->dma_adc.mapped) + { + ret = -ENXIO; + goto out; } continue; } if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { if (!ret) ret = -EFAULT; - break; + goto out; } swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); @@ -1097,6 +1107,8 @@ read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc)); #endif } +out: + up(&s->sem); remove_wait_queue(&s->dma_adc.wait, &wait); set_current_state(TASK_RUNNING); return ret; @@ -1116,10 +1128,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; + #if 0 printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x 71: 0x%02x 72: 0x%02x 74: 0x%02x 76: 0x%02x 78: 0x%02x 7A: 0x%02x\n" KERN_DEBUG "solo1_write: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x SBstat: 0x%02x\n", @@ -1151,20 +1165,27 @@ if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; - break; + goto out; } + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; - break; + 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)) { if (!ret) ret = -EFAULT; - break; + goto out; } swptr = (swptr + cnt) % s->dma_dac.dmasize; spin_lock_irqsave(&s->lock, flags); @@ -1178,6 +1199,8 @@ if (s->dma_dac.enabled) start_dac(s); } +out: + up(&s->sem); remove_wait_queue(&s->dma_dac.wait, &wait); set_current_state(TASK_RUNNING); return ret; @@ -1243,15 +1266,18 @@ if ((ret = prog_dmabuf_adc(s)) != 0) goto out; db = &s->dma_adc; - } else + } else { + 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; @@ -2322,6 +2348,7 @@ init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); + init_MUTEX(&s->sem); spin_lock_init(&s->lock); s->magic = SOLO1_MAGIC; s->dev = pcidev;