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

* Re: patches sound driver locking issue
  2001-06-06 17:07 patches sound driver locking issue Frank Davis
@ 2001-06-06 17:30 ` Jeff Garzik
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff Garzik @ 2001-06-06 17:30 UTC (permalink / raw)
  To: Frank Davis; +Cc: linux-kernel

Frank Davis wrote:
> 
> 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.

Do these patches have the same problems that your es1371 patch did?

Let's make sure that is fixed first, and is solid.

-- 
Jeff Garzik      | Andre the Giant has a posse.
Building 1024    |
MandrakeSoft     |

^ 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