summaryrefslogtreecommitdiffstats
path: root/drivers/sound/es1371.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sound/es1371.c')
-rw-r--r--drivers/sound/es1371.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c
index 2ef9d0bf5..1a4844d47 100644
--- a/drivers/sound/es1371.c
+++ b/drivers/sound/es1371.c
@@ -96,6 +96,8 @@
* detect ES137x chip and derivatives.
* 05.01.2000 0.22 Should now work with rev7 boards; patch by
* Eric Lemar, elemar@cs.washington.edu
+ * 08.01.2000 0.23 Prevent some ioctl's from returning bad count values on underrun/overrun;
+ * Tim Janik's BSE (Bedevilled Sound Engine) found this
*/
/*****************************************************************************/
@@ -1911,6 +1913,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
+ int count;
int val, mapped, ret;
VALIDATE_STATE(s);
@@ -2085,7 +2088,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
abinfo.fragsize = s->dma_dac2.fragsize;
- abinfo.bytes = s->dma_dac2.dmasize - s->dma_dac2.count;
+ count = s->dma_dac2.count;
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = s->dma_dac2.dmasize - count;
abinfo.fragstotal = s->dma_dac2.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
@@ -2099,7 +2105,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
abinfo.fragsize = s->dma_adc.fragsize;
- abinfo.bytes = s->dma_adc.count;
+ count = s->dma_adc.count;
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = count;
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
@@ -2114,9 +2123,11 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -EINVAL;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
- val = s->dma_dac2.count;
+ count = s->dma_dac2.count;
spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *)arg);
+ if (count < 0)
+ count = 0;
+ return put_user(count, (int *)arg);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
@@ -2124,7 +2135,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_adc.total_bytes;
- cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
+ count = s->dma_adc.count;
+ if (count < 0)
+ count = 0;
+ cinfo.blocks = count >> s->dma_adc.fragshift;
cinfo.ptr = s->dma_adc.hwptr;
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
@@ -2137,7 +2151,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_dac2.total_bytes;
- cinfo.blocks = s->dma_dac2.count >> s->dma_dac2.fragshift;
+ count = s->dma_dac2.count;
+ if (count < 0)
+ count = 0;
+ cinfo.blocks = count >> s->dma_dac2.fragshift;
cinfo.ptr = s->dma_dac2.hwptr;
if (s->dma_dac2.mapped)
s->dma_dac2.count &= s->dma_dac2.fragsize-1;
@@ -2430,6 +2447,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
+ int count;
int val, ret;
VALIDATE_STATE(s);
@@ -2529,7 +2547,10 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
abinfo.fragsize = s->dma_dac1.fragsize;
- abinfo.bytes = s->dma_dac1.dmasize - s->dma_dac1.count;
+ count = s->dma_dac1.count;
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = s->dma_dac1.dmasize - count;
abinfo.fragstotal = s->dma_dac1.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
@@ -2542,9 +2563,11 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
case SNDCTL_DSP_GETODELAY:
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
- val = s->dma_dac1.count;
+ count = s->dma_dac1.count;
spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *)arg);
+ if (count < 0)
+ count = 0;
+ return put_user(count, (int *)arg);
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
@@ -2552,7 +2575,10 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_dac1.total_bytes;
- cinfo.blocks = s->dma_dac1.count >> s->dma_dac1.fragshift;
+ count = s->dma_dac1.count;
+ if (count < 0)
+ count = 0;
+ cinfo.blocks = count >> s->dma_dac1.fragshift;
cinfo.ptr = s->dma_dac1.hwptr;
if (s->dma_dac1.mapped)
s->dma_dac1.count &= s->dma_dac1.fragsize-1;
@@ -3229,7 +3255,7 @@ static int __init init_es1371(void)
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "es1371: version v0.22 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1371: version v0.23 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pcidev))) {
if (pcidev->vendor == PCI_VENDOR_ID_ENSONIQ) {
if (pcidev->device != PCI_DEVICE_ID_ENSONIQ_ES1371 &&