All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frank Davis <fdavis112@juno.com>
To: linux-kernel@vger.kernel.org
Cc: fdavis112@juno.com
Subject: patches sound driver locking issue
Date: Wed, 6 Jun 2001 13:07:33 -0400 (EDT)	[thread overview]
Message-ID: <383443482.991847258860.JavaMail.root@web395-wra.mail.com> (raw)

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

             reply	other threads:[~2001-06-06 17:08 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-06-06 17:07 Frank Davis [this message]
2001-06-06 17:30 ` patches sound driver locking issue Jeff Garzik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=383443482.991847258860.JavaMail.root@web395-wra.mail.com \
    --to=fdavis112@juno.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.