Workaround a SoundBlaster 16 OSS bug
Francois Gouget
fgouget at codeweavers.com
Thu Apr 8 19:27:19 CDT 2004
Some SoundBlaster 16 drivers return an incorrect (odd) fragment size for
16 bit sound. Currently our wineoss driver will curse bout this but
faithfully send an odd number of bytes to the OSS driver. Unfortunately
this will cause said driver to enter an infinite loop which causes the
whole kernel to freeze.
So this patch checks if the fragment size is wrong for the current sound
format, curse about it, *and adjust it* to the closest smaller value. I
don't have a test system but it seems to fix the kernel freeze.
For additional information see:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0206.2/0033.html
Note: AFAIK Andreas' kernel patch has never been applied :-(
(now you know how to mount a DOS on these systems!)
Changelog:
* dlls/winmm/wineoss/audio.c
Francois Gouget <fgouget at codeweavers.com>
Patch the fragment size if it does not match the current sound
format. This saves us from trigerring a kernel freeze on some OSS 2.4 +
SounBlaster 16 systems.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /var/cvs/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.122
diff -u -r1.122 audio.c
--- a/dlls/winmm/wineoss/audio.c 31 Mar 2004 19:57:53 -0000 1.122
+++ b/dlls/winmm/wineoss/audio.c 8 Apr 2004 11:19:36 -0000
@@ -1780,6 +1780,18 @@
wwo->dwWrittenTotal = 0;
wwo->bNeedPost = TRUE;
+ TRACE("fd=%d fragstotal=%d fragsize=%d BufferSize=%ld\n",
+ wwo->ossdev->fd, info.fragstotal, info.fragsize, wwo->dwBufferSize);
+ if (wwo->dwFragmentSize % wwo->format.wf.nBlockAlign) {
+ ERR("Fragment doesn't contain an integral number of data blocks fragsize=%ld BlockAlign=%d\n",wwo->dwFragmentSize,wwo->format.wf.nBlockAlign);
+ /* Some SoundBlaster 16 cards return an incorrect (odd) fragment
+ * size for 16 bit sound. This will cause a system crash when we try
+ * to write just the specified odd number of bytes. So if we
+ * detect something is wrong we'd better fix it.
+ */
+ wwo->dwFragmentSize-=wwo->dwFragmentSize % wwo->format.wf.nBlockAlign;
+ }
+
OSS_InitRingMessage(&wwo->msgRing);
wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
@@ -1788,11 +1800,6 @@
CloseHandle(wwo->hStartUpEvent);
wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
- TRACE("fd=%d fragmentSize=%ld\n",
- wwo->ossdev->fd, wwo->dwFragmentSize);
- if (wwo->dwFragmentSize % wwo->format.wf.nBlockAlign)
- ERR("Fragment doesn't contain an integral number of data blocks\n");
-
TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
More information about the wine-patches
mailing list