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)
This commit is contained in:
Ariff Abdullah 2005-11-14 18:20:47 +00:00
parent f95871b97b
commit ee43f8a667
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=152424

View File

@ -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;