linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sound driver locking patches
@ 2001-06-12 23:22 Frank Davis
  0 siblings, 0 replies; only message in thread
From: Frank Davis @ 2001-06-12 23:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: fdavis112

[-- Attachment #1: Type: TEXT/PLAIN, Size: 269 bytes --]

Hello all,
  I have attached sound driver locking patches for:
drivers/sound/cs4281/cs4281m.c
drivers/sound/i810_audio.c

The patches are against 2.4.5-ac13, and address the sound driver locking
issue mentioned in the -ac series.

Please review. Thanks.
Regards,
Frank

[-- Attachment #2: Type: TEXT/PLAIN, Size: 5061 bytes --]

--- drivers/sound/cs4281/cs4281m.c.old	Mon Jun 11 00:23:02 2001\r
+++ drivers/sound/cs4281/cs4281m.c	Tue Jun 12 01:17:14 2001\r
@@ -293,6 +293,7 @@\r
 \r
 	struct cs4281_pm pm;\r
 	struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];\r
+	struct semaphore sem;\r
 };\r
 \r
 #include "cs4281pm-24.c"\r
@@ -2876,7 +2877,7 @@\r
 {\r
 	struct cs4281_state *s =\r
 	    (struct cs4281_state *) file->private_data;\r
-	ssize_t ret;\r
+	ssize_t ret = 0;\r
 	unsigned long flags;\r
 	unsigned swptr;\r
 	int cnt;\r
@@ -2890,11 +2891,12 @@\r
 		return -ESPIPE;\r
 	if (s->dma_adc.mapped)\r
 		return -ENXIO;\r
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))\r
-		return ret;\r
 	if (!access_ok(VERIFY_WRITE, buffer, count))\r
 		return -EFAULT;\r
-	ret = 0;\r
+\r
+	down(&s->sem);\r
+	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))\r
+		goto out;\r
 //\r
 // "count" is the amount of bytes to read (from app), is decremented each loop\r
 //      by the amount of bytes that have been returned to the user buffer.\r
@@ -2950,10 +2952,23 @@\r
 			// the loop when wake up occurs.\r
 			start_adc(s);\r
 			if (file->f_flags & O_NONBLOCK)\r
-				return ret ? ret : -EAGAIN;\r
+			{\r
+				if(!ret) ret = -EAGAIN;\r
+				goto out;\r
+			}\r
+			up(&s->sem);\r
 			interruptible_sleep_on(&s->dma_adc.wait);\r
 			if (signal_pending(current))\r
-				return ret ? ret : -ERESTARTSYS;\r
+			{\r
+				if(!ret) ret = -ERESTARTSYS;\r
+				goto out;\r
+			}\r
+			down(&s->sem);\r
+			if (s->dma_adc.mapped)\r
+			{\r
+				ret = -ENXIO;\r
+				goto out;\r
+			}\r
 			continue;\r
 		}\r
 		// there are bytes in the buffer to read.\r
@@ -2971,7 +2986,10 @@\r
 \r
 		if (cs_copy_to_user\r
 		    (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))\r
-			return ret ? ret : -EFAULT;\r
+			{\r
+			if(!ret) ret = -EFAULT;\r
+			goto out;\r
+			}\r
 		swptr = (swptr + cnt) % s->dma_adc.dmasize;\r
 		spin_lock_irqsave(&s->lock, flags);\r
 		s->dma_adc.swptr = swptr;\r
@@ -2984,6 +3002,8 @@\r
 	}\r
 	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,\r
 		  printk(KERN_INFO "cs4281: cs4281_read()- %d\n", ret));\r
+out:\r
+	up(&s->sem);\r
 	return ret;\r
 }\r
 \r
@@ -3007,10 +3027,12 @@\r
 		return -ESPIPE;\r
 	if (s->dma_dac.mapped)\r
 		return -ENXIO;\r
-	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))\r
-		return ret;\r
 	if (!access_ok(VERIFY_READ, buffer, count))\r
 		return -EFAULT;\r
+	down(&s->sem);\r
+	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))\r
+		goto out;\r
+\r
 	ret = 0;\r
 	while (count > 0) {\r
 		spin_lock_irqsave(&s->lock, flags);\r
@@ -3035,14 +3057,30 @@\r
 		if (cnt <= 0) {\r
 			start_dac(s);\r
 			if (file->f_flags & O_NONBLOCK)\r
-				return ret ? ret : -EAGAIN;\r
+			{\r
+				if(!ret) ret = -EAGAIN;\r
+				goto out;\r
+			}\r
+			up(&s->sem);\r
 			interruptible_sleep_on(&s->dma_dac.wait);\r
 			if (signal_pending(current))\r
-				return ret ? ret : -ERESTARTSYS;\r
+			{\r
+				if(!ret) ret = -ERESTARTSYS;\r
+				goto out;\r
+			}\r
+			down(&s->sem);\r
+			if (s->dma_dac.mapped)\r
+			{\r
+				ret = -ENXIO;\r
+				goto out;\r
+			}\r
 			continue;\r
 		}\r
 		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))\r
-			return ret ? ret : -EFAULT;\r
+		{\r
+			if(!ret) ret = -EFAULT;\r
+			goto out;\r
+		}\r
 		swptr = (swptr + cnt) % s->dma_dac.dmasize;\r
 		spin_lock_irqsave(&s->lock, flags);\r
 		s->dma_dac.swptr = swptr;\r
@@ -3056,6 +3094,8 @@\r
 	}\r
 	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,\r
 		  printk(KERN_INFO "cs4281: cs4281_write()- %d\n", ret));\r
+out:\r
+	up(&s->sem);\r
 	return ret;\r
 }\r
 \r
@@ -3132,35 +3172,49 @@\r
 		  printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));\r
 \r
 	VALIDATE_STATE(s);\r
+	down(&s->sem);\r
 	if (vma->vm_flags & VM_WRITE) {\r
 		if ((ret = prog_dmabuf_dac(s)) != 0)\r
-			return ret;\r
+			goto out;\r
 		db = &s->dma_dac;\r
 	} else if (vma->vm_flags & VM_READ) {\r
 		if ((ret = prog_dmabuf_adc(s)) != 0)\r
-			return ret;\r
+			goto out;\r
 		db = &s->dma_adc;\r
-	} else\r
-		return -EINVAL;\r
+	} else {\r
+		ret = -EINVAL;\r
+		goto out;\r
+	}\r
 //\r
 // only support PLAYBACK for now\r
 //\r
 	db = &s->dma_dac;\r
 \r
 	if (cs4x_pgoff(vma) != 0)\r
-		return -EINVAL;\r
+	{\r
+		ret = -EINVAL;\r
+		goto out;\r
+	}\r
 	size = vma->vm_end - vma->vm_start;\r
 	if (size > (PAGE_SIZE << db->buforder))\r
-		return -EINVAL;\r
+	{\r
+		ret = -EINVAL;\r
+		goto out;\r
+	}\r
 	if (remap_page_range\r
 	    (vma->vm_start, virt_to_phys(db->rawbuf), size,\r
-	     vma->vm_page_prot)) return -EAGAIN;\r
+	     vma->vm_page_prot)) \r
+		{ \r
+		ret = -EAGAIN;\r
+		goto out;\r
+		}\r
 	db->mapped = 1;\r
 \r
 	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,\r
 		  printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",\r
 			 (unsigned) size));\r
-\r
+out:\r
+	up(&s->sem);\r
 	return 0;\r
 }\r
 \r
@@ -4323,6 +4377,7 @@\r
 	init_waitqueue_head(&s->midi.iwait);\r
 	init_waitqueue_head(&s->midi.owait);\r
 	init_MUTEX(&s->open_sem);\r
+	init_MUTEX(&s->sem);\r
 	init_MUTEX(&s->open_sem_adc);\r
 	init_MUTEX(&s->open_sem_dac);\r
 	spin_lock_init(&s->lock);\r

[-- Attachment #3: Type: TEXT/PLAIN, Size: 3920 bytes --]

--- drivers/sound/i810_audio.c.old	Mon Jun 11 00:23:05 2001
+++ drivers/sound/i810_audio.c	Tue Jun 12 19:03:50 2001
@@ -298,6 +298,7 @@
 		unsigned ossmaxfrags;
 		unsigned subdivision;
 	} dmabuf;
+	struct semaphore sem;
 };
 
 
@@ -1066,7 +1067,7 @@
 {
 	struct i810_state *state = (struct i810_state *)file->private_data;
 	struct dmabuf *dmabuf = &state->dmabuf;
-	ssize_t ret;
+	ssize_t ret = 0;
 	unsigned long flags;
 	unsigned int swptr;
 	int cnt;
@@ -1088,13 +1089,14 @@
 			return -EBUSY;
 		}
 	}
-	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-		return ret;
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
 	dmabuf->trigger &= ~PCM_ENABLE_OUTPUT;
-	ret = 0;
 
+	down(&state->sem);
+	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+		goto out;
+	
 	while (count > 0) {
 		spin_lock_irqsave(&state->card->lock, flags);
 		swptr = dmabuf->swptr;
@@ -1119,8 +1121,9 @@
 			}
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
-				return ret;
+				goto out;
 			}
+			up(&state->sem);
 			/* This isnt strictly right for the 810  but it'll do */
 			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
 			tmo >>= 1;
@@ -1142,15 +1145,21 @@
 				   while loop begin and we REALLY have space to record */
 			}
 			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				return ret;
+				if(!ret) ret = -ERESTARTSYS;
+				goto out;
+			}
+			down(&state->sem);
+			if (dmabuf->mapped)
+			{
+				ret = -ENXIO;
+				goto out;
 			}
 			continue;
 		}
 
 		if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
 			if (!ret) ret = -EFAULT;
-			return ret;
+			goto out;
 		}
 
 		swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1164,6 +1173,8 @@
 		buffer += cnt;
 		ret += cnt;
 	}
+out:
+	up(&state->sem);
 	i810_update_lvi(state,1);
 	start_adc(state);
 	return ret;
@@ -1196,11 +1207,12 @@
 		if(!dmabuf->write_channel)
 			return -EBUSY;
 	}
-	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-		return ret;
 	if (!access_ok(VERIFY_READ, buffer, count))
 		return -EFAULT;
 	dmabuf->trigger &= ~PCM_ENABLE_INPUT;
+	down(&state->sem);
+	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
+		goto out;
 	ret = 0;
 
 	while (count > 0) {
@@ -1228,8 +1240,9 @@
 			}
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
-				return ret;
+				goto out;
 			}
+			up(&state->sem);
 			/* Not strictly correct but works */
 			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 4);
 			/* There are two situations when sleep_on_timeout returns, one is when
@@ -1252,13 +1265,19 @@
 			}
 			if (signal_pending(current)) {
 				if (!ret) ret = -ERESTARTSYS;
-				return ret;
+				goto out;
 			}
 			continue;
 		}
+		down(&state->sem);
+		if (dmabuf->mapped)
+		{
+			ret = -ENXIO;
+			goto out;
+		}
 		if (copy_from_user(dmabuf->rawbuf+swptr,buffer,cnt)) {
 			if (!ret) ret = -EFAULT;
-			return ret;
+			goto out;
 		}
 
 		swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1277,6 +1296,8 @@
 		if((x + dmabuf->count) < dmabuf->dmasize)
 			memset(dmabuf->rawbuf + swptr, '\0', x);
 	}
+out:
+	up(&state->sem);
 	i810_update_lvi(state,0);
 	if (!dmabuf->enable && dmabuf->count >= dmabuf->userfragsize)
 		start_dac(state);
@@ -1323,6 +1344,7 @@
 	unsigned long size;
 
 	lock_kernel();
+	down(&state->sem);
 	if (vma->vm_flags & VM_WRITE) {
 		if (!dmabuf->write_channel &&
 		    (dmabuf->write_channel =
@@ -1362,6 +1384,7 @@
 	printk("i810_audio: mmap'ed %ld bytes of data space\n", size);
 #endif
 out:
+	up(&state->sem);
 	unlock_kernel();
 	return ret;
 }
@@ -1784,6 +1807,7 @@
 	state->magic = I810_STATE_MAGIC;
 	init_waitqueue_head(&dmabuf->wait);
 	init_MUTEX(&state->open_sem);
+	init_MUTEX(&state->sem);
 	file->private_data = state;
 	dmabuf->trigger = 0;
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-06-12 23:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-12 23:22 sound driver locking patches Frank Davis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).