From 1a46116d9d39dbbf9b8cadecb5136e69f967110d Mon Sep 17 00:00:00 2001 From: Steven Wallace Date: Wed, 12 Feb 1997 06:56:57 +0000 Subject: [PATCH] Bug fix for SNDCTL_DSP_GETOSPACE ioctl. It would report 0 bytes available in buffer when buffer was completely empty. It now correctly reports the total buffer space available. Reviewed by: jkh, davidg Obtained from: Linux 1.3.20's sound driver code --- sys/i386/include/soundcard.h | 1 + sys/i386/isa/sound/dmabuf.c | 50 +++++++++++++++++++++++++++++++----- sys/sys/soundcard.h | 1 + 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/sys/i386/include/soundcard.h b/sys/i386/include/soundcard.h index a9c04acb976..b19b1906892 100644 --- a/sys/i386/include/soundcard.h +++ b/sys/i386/include/soundcard.h @@ -577,6 +577,7 @@ typedef struct { */ typedef struct audio_buf_info { int fragments; /* # of available fragments (partially usend ones not counted) */ + int fragstotal; /* Total # of fragments allocated */ int fragsize; /* Size of a fragment in bytes */ int bytes; /* Available space in bytes (includes partially used fragments) */ diff --git a/sys/i386/isa/sound/dmabuf.c b/sys/i386/isa/sound/dmabuf.c index 20095d211ab..4211bdb793b 100644 --- a/sys/i386/isa/sound/dmabuf.c +++ b/sys/i386/isa/sound/dmabuf.c @@ -44,6 +44,10 @@ static struct dma_buffparms dmaps[MAX_AUDIO_DEV] = * Needs dynamic run-time alloction. */ +static int space_in_queue (int); +static void reorganize_buffers (int); +static void dma_init_buffers (int); + static void reorganize_buffers (int dev) { @@ -510,14 +514,48 @@ DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) case SNDCTL_DSP_GETOSPACE: if (!local) return RET_ERROR (EINVAL); + else + { + audio_buf_info *info = (audio_buf_info *) arg; - { - audio_buf_info *info = (audio_buf_info *) arg; + if (!(dmap->flags & DMA_ALLOC_DONE)) + reorganize_buffers (dev); - info->fragments = dmap->qlen; - info->fragsize = dmap->fragment_size; - info->bytes = dmap->qlen * dmap->fragment_size; - } + info->fragstotal = dmap->nbufs; + + if (cmd == SNDCTL_DSP_GETISPACE) + info->fragments = dmap->qlen; + else + { + if (!space_in_queue (dev)) + info->fragments = 0; + else + { + info->fragments = dmap->nbufs - dmap->qlen; + if (audio_devs[dev]->local_qlen) + { + int tmp = audio_devs[dev]->local_qlen (dev); + + if (tmp & info->fragments) + tmp--; /* + * This buffer has been counted twice + */ + info->fragments -= tmp; + } + } + } + + if (info->fragments < 0) + info->fragments = 0; + else if (info->fragments > dmap->nbufs) + info->fragments = dmap->nbufs; + + 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]; + } return 0; default: diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h index a9c04acb976..b19b1906892 100644 --- a/sys/sys/soundcard.h +++ b/sys/sys/soundcard.h @@ -577,6 +577,7 @@ typedef struct { */ typedef struct audio_buf_info { int fragments; /* # of available fragments (partially usend ones not counted) */ + int fragstotal; /* Total # of fragments allocated */ int fragsize; /* Size of a fragment in bytes */ int bytes; /* Available space in bytes (includes partially used fragments) */