public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* patches sound driver locking issue
@ 2001-06-06 17:07 Frank Davis
  2001-06-06 17:30 ` Jeff Garzik
  0 siblings, 1 reply; 2+ messages in thread
From: Frank Davis @ 2001-06-06 17:07 UTC (permalink / raw)
  To: linux-kernel; +Cc: fdavis112

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

Hello all,
    I have attached patches against the following sound drivers to fix the locking issues mentioned in Alan's release notes for 2.4.5-ac9 . Please CC me on your comments to the code (I can address the issues quicker). Thanks.
drivers/sound/esssolo1.c
drivers/sound/maestro.c
drivers/sound/maestro3.c
drivers/sound/cmpci.c

Regards,
Frank


[-- Attachment #2: CMPCI_DI --]
[-- Type: text/plain, Size: 5013 bytes --]

--- drivers/sound/cmpci.c.old	Tue Jun  5 21:21:39 2001
+++ drivers/sound/cmpci.c	Tue Jun  5 23:20:41 2001
@@ -312,6 +312,7 @@
 	
 	/* spdif frame counter */
 	int	spdif_counter;
+	struct semaphore sem;
 };
 
 /* flags used for capability */
@@ -1653,7 +1654,7 @@
 static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 {
 	struct cm_state *s = (struct cm_state *)file->private_data;
-	ssize_t ret;
+	ssize_t ret = 0;
 	unsigned long flags;
 	unsigned swptr;
 	int cnt;
@@ -1663,11 +1664,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;
 #if 0
    spin_lock_irqsave(&s->lock, flags);
    cm_update_ptr(s);
@@ -1684,8 +1685,12 @@
 			cnt = count;
 		if (cnt <= 0) {
 			start_adc(s);
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
+			if (file->f_flags & O_NONBLOCK)a
+			{
+				if(!ret) ret = -EAGAIN;
+				goto out;
+			}
+			up(&s->sem);
 			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
 				printk(KERN_DEBUG "cm: 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,
@@ -1698,12 +1703,24 @@
 				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
 				spin_unlock_irqrestore(&s->lock, flags);
 			}
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
+			if (signal_pending(current)) 
+			{
+				if(!ret) ret = -ERESTARTSYS;
+				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))
-			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;
@@ -1714,6 +1731,8 @@
 		start_adc_unlocked(s);
 		spin_unlock_irqrestore(&s->lock, flags);
 	}
+out:
+	up(&s->sem);
 	return ret;
 }
 
@@ -1730,18 +1749,20 @@
 		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;
 	if (s->status & DO_DUAL_DAC) {
 		if (s->dma_adc.mapped)
 			return -ENXIO;
-		if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-			return ret;
 		if (!access_ok(VERIFY_READ, buffer, count))
 			return -EFAULT;
+	down(&s->sem);
+	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+			goto out;
 	}
+	down(&s->sem);
+	if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+		goto out;
 	ret = 0;
 #if 0
    spin_lock_irqsave(&s->lock, flags);
@@ -1776,7 +1797,11 @@
 		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);
 			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
 				printk(KERN_DEBUG "cm: 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,
@@ -1794,7 +1819,16 @@
 				spin_unlock_irqrestore(&s->lock, flags);
 			}
 			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 (s->status & DO_AC3_SW) {
@@ -1818,7 +1852,10 @@
 			swptr = (swptr + cnt) % s->dma_dac.dmasize;
 		} else {
 			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);
@@ -1838,6 +1875,8 @@
 		}
 		start_dac(s);
 	}
+out:
+	up(&s->sem);
 	return ret;
 }
 
@@ -1880,6 +1919,7 @@
 
 	VALIDATE_STATE(s);
 	lock_kernel();
+	down(&s->sem);
 	if (vma->vm_flags & VM_WRITE) {
 		if ((ret = prog_dmabuf(s, 0)) != 0)
 			goto out;
@@ -1888,20 +1928,24 @@
 		if ((ret = prog_dmabuf(s, 1)) != 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 = -EINVAL;
 		goto out;
-	ret = -EINVAL;
+	}
 	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;
 }
@@ -3047,6 +3091,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 = CM_MAGIC;
 		s->iobase = pci_resource_start(pcidev, 0);

[-- Attachment #3: MAESTRO_ --]
[-- Type: text/plain, Size: 4300 bytes --]

--- 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;

[-- Attachment #4: MAESTRO3 --]
[-- Type: text/plain, Size: 4833 bytes --]

--- 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);

[-- Attachment #5: ESSSOLO1 --]
[-- Type: text/plain, Size: 3920 bytes --]

--- 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;

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-06-06 17:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-06-06 17:07 patches sound driver locking issue Frank Davis
2001-06-06 17:30 ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox