summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2005-11-14 18:20:47 +0000
committerariff <ariff@FreeBSD.org>2005-11-14 18:20:47 +0000
commit23cbfb6404aad05209d7d6d35f8b2ad124c13cbf (patch)
treece3e51b6a365a360443b4e05b50464ea81989544 /sys
parent96c796ea3f16c4187623c86aa709b08362521155 (diff)
downloadFreeBSD-src-23cbfb6404aad05209d7d6d35f8b2ad124c13cbf.zip
FreeBSD-src-23cbfb6404aad05209d7d6d35f8b2ad124c13cbf.tar.gz
From luigi:
In SNDCTL_DSP_SETFRAGMENT, if you specify both read and write channels, the existing code first acts on the read channel, but as a side effect it updates the arguments (maxfrags, fragsz) passed by the caller according to acceptable values for the read channel, and then uses the modified values to act on the write channel. The problem with this approach is that, given a (maxfrags, fragsz) user-specified value, the actual values computed by the read and write channels may differ: e.g. the read channel might want to allocate more fragments than what the user specified because it has no side-effects on the delay and it helps in case of slow readers, whereas the write channel needs to use as few fragments as possible to keep the audio latency low (very important with telephony apps). This patch stores the values computed by the read channel into temproary variables so the write channel will use the actual arguments of the ioctl. This patch is very helpful with telephony apps such as asterisk. Submitted by: luigi Approved by: netchild (mentor)
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/pcm/dsp.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 5f94199..1bedd06 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -811,6 +811,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
u_int32_t fragln = (*arg_i) & 0x0000ffff;
u_int32_t maxfrags = ((*arg_i) & 0xffff0000) >> 16;
u_int32_t fragsz;
+ u_int32_t r_maxfrags, r_fragsz;
RANGE(fragln, 4, 16);
fragsz = 1 << fragln;
@@ -826,9 +827,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
if (rdch) {
CHN_LOCK(rdch);
ret = chn_setblocksize(rdch, maxfrags, fragsz);
- maxfrags = sndbuf_getblkcnt(rdch->bufsoft);
- fragsz = sndbuf_getblksz(rdch->bufsoft);
+ r_maxfrags = sndbuf_getblkcnt(rdch->bufsoft);
+ r_fragsz = sndbuf_getblksz(rdch->bufsoft);
CHN_UNLOCK(rdch);
+ } else {
+ r_maxfrags = maxfrags;
+ r_fragsz = fragsz;
}
if (wrch && ret == 0) {
CHN_LOCK(wrch);
@@ -836,6 +840,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
maxfrags = sndbuf_getblkcnt(wrch->bufsoft);
fragsz = sndbuf_getblksz(wrch->bufsoft);
CHN_UNLOCK(wrch);
+ } else { /* use whatever came from the read channel */
+ maxfrags = r_maxfrags;
+ fragsz = r_fragsz;
}
fragln = 0;
OpenPOWER on IntegriCloud