Skip to contentSkip to conversation

patches sound driver locking issue

PATCH Frank Davis 2 participants 2 messages Jun 6, 2001 Sound

lore
Share & tools
lore
#0 lore raw

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

sound/cmpci.c renamed from sound/cmpci.c.old +64 -19
@@ -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);
sound/maestro.c renamed from sound/maestro.c.old +37 -13

161 lines not on this page · raw message

sound/maestro3.c renamed from sound/maestro3.c.old +42 -18

176 lines not on this page · raw message

sound/esssolo1.c renamed from sound/esssolo1.c.old +42 -15

151 lines not on this page · raw message

#1 lore raw
Quoted 3 lines · Frank Davis

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.

Signature · 3 lines
Jeff Garzik      | Andre the Giant has a posse.
Building 1024    |
MandrakeSoft     |