Subject: kern/9203: Audio driver should round the buffer size to its requirements
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dave@dtsp.co.nz>
List: netbsd-bugs
Date: 01/15/2000 17:43:21
>Number:         9203
>Category:       kern
>Synopsis:       Audio driver should round the buffer size to its requirements
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jan 15 17:42:00 2000
>Last-Modified:
>Originator:     Dave Sainty
>Organization:
Dynamic Technology Services and Products Ltd (NZ)
>Release:        Recent current
>Environment:
System: NetBSD tequila.dave.dtsp.co.nz 1.4P NetBSD 1.4P (TEQUILA) #1: Wed Jan 12 09:00:09 NZDT 2000 dave@tequila.dave.dtsp.co.nz:/vol/tequila/userB/u2/NetBSD-current/src/sys/arch/i386/compile/TEQUILA i386


>Description:
	sys/dev/audio.c makes some assumptions about the buffer size presented
	by the drivers.  In particular it assumes its length is a multiple of
	2, because it assumes that if it audio_fill_silence()'s, the end of
	the buffer will cleanly wrap onto the start of the buffer.

	That probably actually means it isn't safe to use a buffer length that
	isn't a multiple of 4 (16 bit stereo).  (What about 3, 4, 5 or... 5.1
	channels?)

	At least one driver currently returns an odd-sized buffer length
	(eso.c, 65535 bytes).
>How-To-Repeat:
	Inspection, see audio_mmap() in audio.c for one (possibly the only
	case?), which explicitly audio_fill_silence()'s the buffer (and will
	in fact buffer overrun by one byte if the buffer length is odd and the
	audio format is 16 bit).
>Fix:
	The correct fix is to audio.c, not to the individual drivers.
	Whatever rounding audio.c needs now may change at a later date.

	Currently audio.c has no provision for changing the buffer lengths
	depending on format, so the patch included selects one
	buffer size that audio.c is happy with for all audio formats.

	This patch applies an even more extreme rounding to the buffer size
	(16 bytes) than strictly necessary.  It is worth rounding twice, to
	ensure that the buffer size passed to the hardware driver is actually
	acceptable to start with.

--- audio.c.orig        Wed Dec 29 14:06:01 1999
+++ audio.c     Sun Jan 16 14:20:13 2000
@@ -523,8 +523,10 @@
        if (bufsize < AUMINBUF)
                bufsize = AUMINBUF;
        ROUNDSIZE(bufsize);
-       if (hw->round_buffersize)
+       if (hw->round_buffersize) {
                bufsize = hw->round_buffersize(hdl, direction, bufsize);
+               ROUNDSIZE(bufsize);
+       }
        if (hw->allocm)
                r->start = hw->allocm(hdl, direction, bufsize, M_DEVBUF, M_WAITOK);
        else
>Audit-Trail:
>Unformatted: