patch-2.1.80 linux/drivers/sound/audio.c
Next file: linux/drivers/sound/cs4232.c
Previous file: linux/drivers/sound/adlib_card.c
Back to the patch index
Back to the overall index
- Lines: 704
- Date:
Tue Jan 20 16:44:57 1998
- Orig file:
v2.1.79/linux/drivers/sound/audio.c
- Orig date:
Fri Jan 2 14:37:02 1998
diff -u --recursive --new-file v2.1.79/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
@@ -362,144 +362,151 @@
/* else
printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
return -ENXIO;
- } else switch (cmd) {
- case SNDCTL_DSP_SYNC:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ }
+ else switch (cmd)
+ {
+ case SNDCTL_DSP_SYNC:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return 0;
+ if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ return 0;
+ sync_output(dev);
+ DMAbuf_sync(dev);
+ DMAbuf_reset(dev);
return 0;
- sync_output(dev);
- DMAbuf_sync(dev);
- DMAbuf_reset(dev);
- return 0;
- case SNDCTL_DSP_POST:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ case SNDCTL_DSP_POST:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return 0;
+ if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ return 0;
+ audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
+ sync_output(dev);
+ dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
return 0;
- audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
- sync_output(dev);
- dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
- return 0;
-
- case SNDCTL_DSP_RESET:
- audio_mode[dev] = AM_NONE;
- DMAbuf_reset(dev);
- return 0;
-
- case SNDCTL_DSP_GETFMTS:
- val = audio_devs[dev]->format_mask;
- return __put_user(val, (int *)arg);
-
- case SNDCTL_DSP_SETFMT:
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- val = set_format(dev, val);
- return __put_user(val, (int *)arg);
- case SNDCTL_DSP_GETISPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ case SNDCTL_DSP_RESET:
+ audio_mode[dev] = AM_NONE;
+ DMAbuf_reset(dev);
return 0;
- if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
- return dma_ioctl(dev, cmd, arg);
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EPERM;
- if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
- return dma_ioctl(dev, cmd, arg);
+
+ case SNDCTL_DSP_GETFMTS:
+ val = audio_devs[dev]->format_mask;
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = set_format(dev, val);
+ break;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ return 0;
+ if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
+ return dma_ioctl(dev, cmd, arg);
+
+ case SNDCTL_DSP_GETOSPACE:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EPERM;
+ if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
+ return dma_ioctl(dev, cmd, arg);
- case SNDCTL_DSP_NONBLOCK:
- dev_nblock[dev] = 1;
- return 0;
-
- case SNDCTL_DSP_GETCAPS:
- info = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
- if (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode == OPEN_READWRITE)
- info |= DSP_CAP_DUPLEX;
- if (audio_devs[dev]->coproc)
- info |= DSP_CAP_COPROC;
- if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
- info |= DSP_CAP_BATCH;
- if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
- info |= DSP_CAP_TRIGGER;
- return __put_user(info, (int *)arg);
+ case SNDCTL_DSP_NONBLOCK:
+ dev_nblock[dev] = 1;
+ return 0;
+
+ case SNDCTL_DSP_GETCAPS:
+ info = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
+ if (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode == OPEN_READWRITE)
+ info |= DSP_CAP_DUPLEX;
+ if (audio_devs[dev]->coproc)
+ info |= DSP_CAP_COPROC;
+ if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
+ info |= DSP_CAP_BATCH;
+ if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
+ info |= DSP_CAP_TRIGGER;
+ break;
- case SOUND_PCM_WRITE_RATE:
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- val = audio_devs[dev]->d->set_speed(dev, val);
- return __put_user(val, (int *)arg);
-
- case SOUND_PCM_READ_RATE:
- val = audio_devs[dev]->d->set_speed(dev, 0);
- return __put_user(val, (int *)arg);
-
- case SNDCTL_DSP_STEREO:
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- if (val > 1 || val < 0)
- return -EINVAL;
- val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
- return __put_user(val, (int *)arg);
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- val = audio_devs[dev]->d->set_channels(dev, val);
- return __put_user(val, (int *)arg);
-
- case SOUND_PCM_READ_CHANNELS:
- val = audio_devs[dev]->d->set_channels(dev, 0);
- return __put_user(val, (int *)arg);
+ case SOUND_PCM_WRITE_RATE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = audio_devs[dev]->d->set_speed(dev, val);
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ val = audio_devs[dev]->d->set_speed(dev, 0);
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val > 1 || val < 0)
+ return -EINVAL;
+ val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = audio_devs[dev]->d->set_channels(dev, val);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ val = audio_devs[dev]->d->set_channels(dev, 0);
+ break;
- case SOUND_PCM_READ_BITS:
- val = audio_devs[dev]->d->set_bits(dev, 0);
- return __put_user(val, (int *)arg);
-
- case SNDCTL_DSP_SETDUPLEX:
- if (audio_devs[dev]->open_mode != OPEN_READWRITE)
- return -EPERM;
- return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
-
- case SNDCTL_DSP_PROFILE:
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- audio_devs[dev]->dmap_out->applic_profile = val;
- if (audio_devs[dev]->open_mode & OPEN_READ)
- audio_devs[dev]->dmap_in->applic_profile = val;
- return 0;
+ case SOUND_PCM_READ_BITS:
+ val = audio_devs[dev]->d->set_bits(dev, 0);
+ break;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ if (audio_devs[dev]->open_mode != OPEN_READWRITE)
+ return -EPERM;
+ return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
+
+ case SNDCTL_DSP_PROFILE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ audio_devs[dev]->dmap_out->applic_profile = val;
+ if (audio_devs[dev]->open_mode & OPEN_READ)
+ audio_devs[dev]->dmap_in->applic_profile = val;
+ return 0;
- case SNDCTL_DSP_GETODELAY:
- dmap = audio_devs[dev]->dmap_out;
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (!(dmap->flags & DMA_ALLOC_DONE))
- return __put_user(0, (int *)arg);
+ case SNDCTL_DSP_GETODELAY:
+ dmap = audio_devs[dev]->dmap_out;
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+ if (!(dmap->flags & DMA_ALLOC_DONE))
+ {
+ val=0;
+ break;
+ }
- save_flags (flags);
- cli();
- /* Compute number of bytes that have been played */
- count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
- if (count < dmap->fragment_size && dmap->qhead != 0)
- count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
- count += dmap->byte_counter;
+ save_flags (flags);
+ cli();
+ /* Compute number of bytes that have been played */
+ count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
+ if (count < dmap->fragment_size && dmap->qhead != 0)
+ count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
+ count += dmap->byte_counter;
- /* Substract current count from the number of bytes written by app */
- count = dmap->user_counter - count;
- if (count < 0)
- count = 0;
- restore_flags (flags);
- return __put_user(count, (int *)arg);
+ /* Substract current count from the number of bytes written by app */
+ count = dmap->user_counter - count;
+ if (count < 0)
+ count = 0;
+ restore_flags (flags);
+ val = count;
+ break;
- default:
- return dma_ioctl(dev, cmd, arg);
+ default:
+ return dma_ioctl(dev, cmd, arg);
}
+ return put_user(val, (int *)arg);
}
void audio_init_devices(void)
@@ -641,7 +648,8 @@
static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
{
- if (fact == 0) {
+ if (fact == 0)
+ {
fact = dmap->subdivision;
if (fact == 0)
fact = 1;
@@ -722,210 +730,222 @@
int fact, ret, changed, bits, count, err;
unsigned long flags;
- switch (cmd) {
- case SNDCTL_DSP_SUBDIVIDE:
- ret = 0;
- if (__get_user(fact, (int *)arg))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- ret = dma_subdivide(dev, dmap_out, fact);
- if (ret < 0)
- return ret;
- if (audio_devs[dev]->open_mode != OPEN_WRITE ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- ret = dma_subdivide(dev, dmap_in, fact);
- if (ret < 0)
- return ret;
- return __put_user(ret, (int *)arg);
-
- case SNDCTL_DSP_GETISPACE:
- case SNDCTL_DSP_GETOSPACE:
- dmap = dmap_out;
- if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
- if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
- dmap = dmap_in;
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return -EINVAL;
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
- info.fragstotal = dmap->nbufs;
- if (cmd == SNDCTL_DSP_GETISPACE)
- info.fragments = dmap->qlen;
- else {
- if (!DMAbuf_space_in_queue(dev))
- info.fragments = 0;
- else {
- info.fragments = DMAbuf_space_in_queue(dev);
- if (audio_devs[dev]->d->local_qlen) {
- int tmp = audio_devs[dev]->d->local_qlen(dev);
- if (tmp && info.fragments)
- tmp--; /*
- * This buffer has been counted twice
- */
- info.fragments -= tmp;
+ switch (cmd)
+ {
+ case SNDCTL_DSP_SUBDIVIDE:
+ ret = 0;
+ if (get_user(fact, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ ret = dma_subdivide(dev, dmap_out, fact);
+ if (ret < 0)
+ return ret;
+ if (audio_devs[dev]->open_mode != OPEN_WRITE ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ ret = dma_subdivide(dev, dmap_in, fact);
+ if (ret < 0)
+ return ret;
+ break;
+
+ case SNDCTL_DSP_GETISPACE:
+ case SNDCTL_DSP_GETOSPACE:
+ dmap = dmap_out;
+ if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
+ return -EINVAL;
+ if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+ if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
+ dmap = dmap_in;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ return -EINVAL;
+ if (!(dmap->flags & DMA_ALLOC_DONE))
+ reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
+ info.fragstotal = dmap->nbufs;
+ if (cmd == SNDCTL_DSP_GETISPACE)
+ info.fragments = dmap->qlen;
+ else
+ {
+ if (!DMAbuf_space_in_queue(dev))
+ info.fragments = 0;
+ else
+ {
+ info.fragments = DMAbuf_space_in_queue(dev);
+ if (audio_devs[dev]->d->local_qlen)
+ {
+ int tmp = audio_devs[dev]->d->local_qlen(dev);
+ if (tmp && info.fragments)
+ tmp--; /*
+ * This buffer has been counted twice
+ */
+ info.fragments -= tmp;
+ }
}
}
- }
- if (info.fragments < 0)
+ if (info.fragments < 0)
info.fragments = 0;
- else if (info.fragments > dmap->nbufs)
- info.fragments = dmap->nbufs;
+ else if (info.fragments > dmap->nbufs)
+ info.fragments = dmap->nbufs;
- info.fragsize = dmap->fragment_size;
- info.bytes = info.fragments * dmap->fragment_size;
+ info.fragsize = dmap->fragment_size;
+ info.bytes = info.fragments * dmap->fragment_size;
- if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
- info.bytes -= dmap->counts[dmap->qhead];
- else {
- info.fragments = info.bytes / dmap->fragment_size;
- info.bytes -= dmap->user_counter % dmap->fragment_size;
- }
- return __copy_to_user(arg, &info, sizeof(info));
+ if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
+ info.bytes -= dmap->counts[dmap->qhead];
+ else
+ {
+ info.fragments = info.bytes / dmap->fragment_size;
+ info.bytes -= dmap->user_counter % dmap->fragment_size;
+ }
+ return copy_to_user(arg, &info, sizeof(info));
- case SNDCTL_DSP_SETTRIGGER:
- if (__get_user(bits, (int *)arg))
- return -EFAULT;
- bits &= audio_devs[dev]->open_mode;
- if (audio_devs[dev]->d->trigger == NULL)
- return -EINVAL;
- if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
- (bits & PCM_ENABLE_OUTPUT))
- return -EINVAL;
- save_flags(flags);
- cli();
- changed = audio_devs[dev]->enable_bits ^ bits;
- if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go) {
- reorganize_buffers(dev, dmap_in, 1);
- if ((err = audio_devs[dev]->d->prepare_for_input(dev,
+ case SNDCTL_DSP_SETTRIGGER:
+ if (get_user(bits, (int *)arg))
+ return -EFAULT;
+ bits &= audio_devs[dev]->open_mode;
+ if (audio_devs[dev]->d->trigger == NULL)
+ return -EINVAL;
+ if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
+ (bits & PCM_ENABLE_OUTPUT))
+ return -EINVAL;
+ save_flags(flags);
+ cli();
+ changed = audio_devs[dev]->enable_bits ^ bits;
+ if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
+ {
+ reorganize_buffers(dev, dmap_in, 1);
+ if ((err = audio_devs[dev]->d->prepare_for_input(dev,
dmap_in->fragment_size, dmap_in->nbufs)) < 0)
- return -err;
- dmap_in->dma_mode = DMODE_INPUT;
+ return -err;
+ dmap_in->dma_mode = DMODE_INPUT;
+ audio_devs[dev]->enable_bits = bits;
+ DMAbuf_activate_recording(dev, dmap_in);
+ }
+ if ((changed & bits) & PCM_ENABLE_OUTPUT &&
+ (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
+ audio_devs[dev]->go)
+ {
+ if (!(dmap_out->flags & DMA_ALLOC_DONE))
+ reorganize_buffers(dev, dmap_out, 0);
+ dmap_out->dma_mode = DMODE_OUTPUT;
+ audio_devs[dev]->enable_bits = bits;
+ dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
+ DMAbuf_launch_output(dev, dmap_out);
+ }
audio_devs[dev]->enable_bits = bits;
- DMAbuf_activate_recording(dev, dmap_in);
- }
- if ((changed & bits) & PCM_ENABLE_OUTPUT &&
- (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
- audio_devs[dev]->go) {
+ if (changed && audio_devs[dev]->d->trigger)
+ audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
+ restore_flags(flags);
+ /* Falls through... */
+
+ case SNDCTL_DSP_GETTRIGGER:
+ ret = audio_devs[dev]->enable_bits;
+ break;
+
+ case SNDCTL_DSP_SETSYNCRO:
+ if (!audio_devs[dev]->d->trigger)
+ return -EINVAL;
+ audio_devs[dev]->d->trigger(dev, 0);
+ audio_devs[dev]->go = 0;
+ return 0;
+
+ case SNDCTL_DSP_GETIPTR:
+ if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ return -EINVAL;
+ save_flags(flags);
+ cli();
+ cinfo.bytes = dmap_in->byte_counter;
+ cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
+ if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
+ cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
+ cinfo.blocks = dmap_in->qlen;
+ cinfo.bytes += cinfo.ptr;
+ if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
+ dmap_in->qlen = 0; /* Reset interrupt counter */
+ restore_flags(flags);
+ return copy_to_user(arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETOPTR:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+
+ save_flags(flags);
+ cli();
+ cinfo.bytes = dmap_out->byte_counter;
+ cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
+ if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
+ cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
+ cinfo.blocks = dmap_out->qlen;
+ cinfo.bytes += cinfo.ptr;
+ if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
+ dmap_out->qlen = 0; /* Reset interrupt counter */
+ restore_flags(flags);
+ return copy_to_user(arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
if (!(dmap_out->flags & DMA_ALLOC_DONE))
- reorganize_buffers(dev, dmap_out, 0);
- dmap_out->dma_mode = DMODE_OUTPUT;
- audio_devs[dev]->enable_bits = bits;
- dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
- DMAbuf_launch_output(dev, dmap_out);
- }
- audio_devs[dev]->enable_bits = bits;
- if (changed && audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
- restore_flags(flags);
- /* Falls through... */
-
- case SNDCTL_DSP_GETTRIGGER:
- ret = audio_devs[dev]->enable_bits;
- return __put_user(ret, (int *)arg);
-
- case SNDCTL_DSP_SETSYNCRO:
- if (!audio_devs[dev]->d->trigger)
- return -EINVAL;
- audio_devs[dev]->d->trigger(dev, 0);
- audio_devs[dev]->go = 0;
- return 0;
-
- case SNDCTL_DSP_GETIPTR:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
- save_flags(flags);
- cli();
- cinfo.bytes = dmap_in->byte_counter;
- cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
- if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
- cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
- cinfo.blocks = dmap_in->qlen;
- cinfo.bytes += cinfo.ptr;
- if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
- dmap_in->qlen = 0; /* Reset interrupt counter */
- restore_flags(flags);
- return __copy_to_user(arg, &cinfo, sizeof(cinfo));
-
- case SNDCTL_DSP_GETOPTR:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
-
- save_flags(flags);
- cli();
- cinfo.bytes = dmap_out->byte_counter;
- cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
- if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
- cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
- cinfo.blocks = dmap_out->qlen;
- cinfo.bytes += cinfo.ptr;
- if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
- dmap_out->qlen = 0; /* Reset interrupt counter */
- restore_flags(flags);
- return __copy_to_user(arg, &cinfo, sizeof(cinfo));
-
- case SNDCTL_DSP_GETODELAY:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (!(dmap_out->flags & DMA_ALLOC_DONE))
- return __put_user(0, (int *)arg);
- save_flags(flags);
- cli();
- /* Compute number of bytes that have been played */
- count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
- if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
- count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
- count += dmap_out->byte_counter;
- /* Substract current count from the number of bytes written by app */
- count = dmap_out->user_counter - count;
- if (count < 0)
- count = 0;
- restore_flags (flags);
- return __put_user(count, (int *)arg);
-
- case SNDCTL_DSP_POST:
- if (audio_devs[dev]->dmap_out->qlen > 0)
- if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
- DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
- return 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- dmap = dmap_out;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode == OPEN_READ ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode == OPEN_READ)
- dmap = dmap_in;
- ret = dmap->fragment_size;
- return __put_user(ret, (int *)arg);
-
- case SNDCTL_DSP_SETFRAGMENT:
- ret = 0;
- if (__get_user(fact, (int *)arg))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- ret = dma_set_fragment(dev, dmap_out, fact);
- if (ret < 0)
- return ret;
- if (audio_devs[dev]->open_mode == OPEN_READ ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- ret = dma_set_fragment(dev, dmap_in, fact);
- if (ret < 0)
- return ret;
- if (!arg) /* don't know what this is good for, but preserve old semantics */
+ {
+ ret=0;
+ break;
+ }
+ save_flags(flags);
+ cli();
+ /* Compute number of bytes that have been played */
+ count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
+ if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
+ count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
+ count += dmap_out->byte_counter;
+ /* Substract current count from the number of bytes written by app */
+ count = dmap_out->user_counter - count;
+ if (count < 0)
+ count = 0;
+ restore_flags (flags);
+ ret = count;
+ break;
+
+ case SNDCTL_DSP_POST:
+ if (audio_devs[dev]->dmap_out->qlen > 0)
+ if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
+ DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
return 0;
- return __put_user(ret, (int *)arg);
- default:
- if (!audio_devs[dev]->d->ioctl)
- return -EINVAL;
- return audio_devs[dev]->d->ioctl(dev, cmd, arg);
+ case SNDCTL_DSP_GETBLKSIZE:
+ dmap = dmap_out;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
+ if (audio_devs[dev]->open_mode == OPEN_READ ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
+ if (audio_devs[dev]->open_mode == OPEN_READ)
+ dmap = dmap_in;
+ ret = dmap->fragment_size;
+ break;
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ ret = 0;
+ if (get_user(fact, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ ret = dma_set_fragment(dev, dmap_out, fact);
+ if (ret < 0)
+ return ret;
+ if (audio_devs[dev]->open_mode == OPEN_READ ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ ret = dma_set_fragment(dev, dmap_in, fact);
+ if (ret < 0)
+ return ret;
+ if (!arg) /* don't know what this is good for, but preserve old semantics */
+ return 0;
+ break;
+
+ default:
+ if (!audio_devs[dev]->d->ioctl)
+ return -EINVAL;
+ return audio_devs[dev]->d->ioctl(dev, cmd, arg);
}
+ return put_user(ret, (int *)arg);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov