Skip to contentSkip to conversation

: 2.4.0-test11: sound drivers, again

PATCH New Tjeerd Mulder 1 participant 1 message Nov 30, 2000

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 : 2.4.0-test11: sound drivers, again

In http://www.cs.helsinki.fi/linux/linux-kernel/2000-47/0343.html
Thomas Sailer posted a patch to some ac97 sound drivers. Because this patch is not in 2.4.0-test12-pre2 I post the same patch again with some additions where the same bug does occur.

The bug is that dma buffer are not yet allocated, leading to division by zero (dma buffer size).

kscdmagic triggers the bug because it does a ioctl GETIPTR before ever reading from the device. The read would have allocated the dma buffer.

The i810_audio driver is not included in this patch because I have a seperate patch for that with a few more bug fixes.

I tested the maestro, cs4281, esssolo1, sonicvibes drivers:
of these the sonicvibes worked, the solo1 could only output, the cs4281 failed to initialize its hardware and the maestro crashed my system, and that is NOT due to this patch !

drivers/sound/cmpci.c +19 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/cmpci.c linux-2.4.0-test11-clean/drivers/sound/cmpci.c
@@ -1373,10 +1373,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready && prog_dmabuf(s, 0))
+			return 0;
 		poll_wait(file, &s->dma_dac.wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready && prog_dmabuf(s, 1))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
 	spin_lock_irqsave(&s->lock, flags);
 	cm_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1604,8 +1611,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->enable & CM_CENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
 		abinfo.fragsize = s->dma_dac.fragsize;
@@ -1618,8 +1625,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->enable & CM_CENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1636,6 +1643,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 val = s->dma_dac.count;
@@ -1645,6 +1654,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1658,6 +1669,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 cinfo.bytes = s->dma_dac.total_bytes;
drivers/sound/cs4281.c +16 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/cs4281.c linux-2.4.0-test11-clean/drivers/sound/cs4281.c
@@ -2489,14 +2489,19 @@
 		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
 			  printk(KERN_INFO
 				 "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
+		if (!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
 		poll_wait(file, &s->dma_dac.wait, wait);
 	}
 	if (file->f_mode & FMODE_READ) {
 		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
 			  printk(KERN_INFO
 				 "cs4281: cs4281_poll() wait on FMODE_READ\n"));
+		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
 	}
+
 	spin_lock_irqsave(&s->lock, flags);
 	cs4281_update_ptr(s);
 	if (file->f_mode & FMODE_WRITE) {
@@ -2516,8 +2521,8 @@
 	} else if (file->f_mode & FMODE_READ) {
 		if (s->dma_adc.mapped) {
 			if (s->dma_adc.count >=
-			    (signed) s->dma_adc.fragsize) mask |=
-				    POLLIN | POLLRDNORM;
+			    (signed) s->dma_adc.fragsize)
+				mask |= POLLIN | POLLRDNORM;
 		} else {
 			if (s->dma_adc.count > 0)
 				mask |= POLLIN | POLLRDNORM;
@@ -2836,8 +2841,7 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->ena & FMODE_WRITE)
-		    && (val = prog_dmabuf_dac(s)) != 0)
+		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
 			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cs4281_update_ptr(s);
@@ -2865,8 +2869,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->ena & FMODE_READ)
-		    && (val = prog_dmabuf_adc(s)) != 0) return val;
+		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cs4281_update_ptr(s);
 		if (s->conversion) {
@@ -2893,6 +2897,8 @@
 	case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cs4281_update_ptr(s);
 		val = s->dma_dac.count;
@@ -2902,6 +2908,8 @@
 	case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cs4281_update_ptr(s);
 		cinfo.bytes = s->dma_adc.total_bytes;
@@ -2933,6 +2941,8 @@
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cs4281_update_ptr(s);
 		cinfo.bytes = s->dma_dac.total_bytes;
drivers/sound/cs46xx.c +16 -4
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/cs46xx.c linux-2.4.0-test11-clean/drivers/sound/cs46xx.c
@@ -1124,10 +1124,16 @@
 	unsigned long flags;
 	unsigned int mask = 0;
 
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!dmabuf->ready && prog_dmabuf(state, 0))
+			return 0;
 		poll_wait(file, &dmabuf->wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!dmabuf->ready && prog_dmabuf(state, 1))
+			return 0;
 		poll_wait(file, &dmabuf->wait, wait);
+	}
 
 	spin_lock_irqsave(&state->card->lock, flags);
 	cs_update_ptr(state);
@@ -1368,7 +1374,7 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		cs_update_ptr(state);
@@ -1382,7 +1388,7 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		cs_update_ptr(state);
@@ -1433,6 +1439,8 @@
 	case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		cs_update_ptr(state);
 		cinfo.bytes = dmabuf->total_bytes;
@@ -1446,6 +1454,8 @@
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		cs_update_ptr(state);
 		cinfo.bytes = dmabuf->total_bytes;
@@ -1462,6 +1472,8 @@
 	case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		cs_update_ptr(state);
 		val = dmabuf->count;
drivers/sound/es1370.c +19 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/es1370.c linux-2.4.0-test11-clean/drivers/sound/es1370.c
@@ -1280,10 +1280,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
+			return 0;
 		poll_wait(file, &s->dma_dac2.wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+		 
 	spin_lock_irqsave(&s->lock, flags);
 	es1370_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1530,8 +1537,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
 		abinfo.fragsize = s->dma_dac2.fragsize;
@@ -1547,8 +1554,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->ctrl & CTRL_ADC_EN) && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1568,6 +1575,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
                 count = s->dma_dac2.count;
@@ -1579,6 +1588,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1595,6 +1606,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
                 cinfo.bytes = s->dma_dac2.total_bytes;
drivers/sound/es1371.c +19 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/es1371.c linux-2.4.0-test11-clean/drivers/sound/es1371.c
@@ -1463,10 +1463,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
+			return 0;
 		poll_wait(file, &s->dma_dac2.wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
 	spin_lock_irqsave(&s->lock, flags);
 	es1371_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1710,8 +1717,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
 		abinfo.fragsize = s->dma_dac2.fragsize;
@@ -1727,8 +1734,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->ctrl & CTRL_ADC_EN) && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1748,6 +1755,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
                 count = s->dma_dac2.count;
@@ -1759,6 +1768,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1775,6 +1786,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
                 cinfo.bytes = s->dma_dac2.total_bytes;
drivers/sound/esssolo1.c +19 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/esssolo1.c linux-2.4.0-test11-clean/drivers/sound/esssolo1.c
@@ -1168,10 +1168,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
 		poll_wait(file, &s->dma_dac.wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
 	spin_lock_irqsave(&s->lock, flags);
 	solo1_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1382,8 +1389,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->ena & FMODE_WRITE) && (val = prog_dmabuf_dac(s)) != 0)
-			return val;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		solo1_update_ptr(s);
 		abinfo.fragsize = s->dma_dac.fragsize;
@@ -1399,8 +1406,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->ena & FMODE_READ) && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		solo1_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1417,6 +1424,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		solo1_update_ptr(s);
                 count = s->dma_dac.count;
@@ -1428,6 +1437,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		solo1_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1441,6 +1452,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		solo1_update_ptr(s);
                 cinfo.bytes = s->dma_dac.total_bytes;
drivers/sound/maestro.c +14 -9
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/maestro.c linux-2.4.0-test11-clean/drivers/sound/maestro.c
@@ -2384,18 +2384,17 @@
 	struct ess_state *s = (struct ess_state *)file->private_data;
 	unsigned long flags;
 	unsigned int mask = 0;
-	int ret;
 
 	VALIDATE_STATE(s);
 
 /* In 0.14 prog_dmabuf always returns success anyway ... */
 	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) 
-			return POLLERR;
+		if (!s->dma_dac.ready && prog_dmabuf(s, 0)) 
+			return 0;
 	}
 	if (file->f_mode & FMODE_READ) {
-	  	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-			return POLLERR;
+	  	if (!s->dma_adc.ready && prog_dmabuf(s, 1))
+			return 0;
 	}
 
 	if (file->f_mode & FMODE_WRITE)
@@ -2645,8 +2644,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		ess_update_ptr(s);
 		abinfo.fragsize = s->dma_dac.fragsize;
@@ -2659,8 +2658,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		ess_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -2677,6 +2676,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		ess_update_ptr(s);
                 val = s->dma_dac.count;
@@ -2686,6 +2687,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		ess_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -2699,6 +2702,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		ess_update_ptr(s);
                 cinfo.bytes = s->dma_dac.total_bytes;
drivers/sound/sonicvibes.c +19 -6
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/sonicvibes.c linux-2.4.0-test11-clean/drivers/sound/sonicvibes.c
@@ -1484,10 +1484,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready && prog_dmabuf(s, 0))
+			return 0;
 		poll_wait(file, &s->dma_dac.wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready && prog_dmabuf(s, 1))
+			return 0;
 		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
 	spin_lock_irqsave(&s->lock, flags);
 	sv_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1716,8 +1723,8 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!(s->enable & SV_CENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		sv_update_ptr(s);
 		abinfo.fragsize = s->dma_dac.fragsize;
@@ -1733,8 +1740,8 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!(s->enable & SV_CENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		sv_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1754,6 +1761,8 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		sv_update_ptr(s);
                 count = s->dma_dac.count;
@@ -1765,6 +1774,8 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		sv_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1781,6 +1792,8 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		sv_update_ptr(s);
                 cinfo.bytes = s->dma_dac.total_bytes;
drivers/sound/trident.c +17 -4
diff -u --recursive linux-2.4.0-test11-org/drivers/sound/trident.c linux-2.4.0-test11-clean/drivers/sound/trident.c
@@ -1595,10 +1595,17 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(state);
-	if (file->f_mode & FMODE_WRITE)
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!dmabuf->ready && prog_dmabuf(state, 0))
+			return 0;
 		poll_wait(file, &dmabuf->wait, wait);
-	if (file->f_mode & FMODE_READ)
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!dmabuf->ready && prog_dmabuf(state, 1))
+			return 0;
 		poll_wait(file, &dmabuf->wait, wait);
+	}
 
 	spin_lock_irqsave(&state->card->lock, flags);
 	trident_update_ptr(state);
@@ -1866,7 +1873,7 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		trident_update_ptr(state);
@@ -1880,7 +1887,7 @@
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		trident_update_ptr(state);
@@ -1931,6 +1938,8 @@
 	case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		trident_update_ptr(state);
 		cinfo.bytes = dmabuf->total_bytes;
@@ -1944,6 +1953,8 @@
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		trident_update_ptr(state);
 		cinfo.bytes = dmabuf->total_bytes;
@@ -1960,6 +1971,8 @@
 	case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		trident_update_ptr(state);
 		val = dmabuf->count;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/