Hello!
The implementation of SNDCTL_DSP_SETFRAGMENT in ymfpci.c is too hacky (as
of 2.4.1-ac3). The comment says that it was done for Doom only.
The attached patch makes the implementation of SNDCTL_DSP_SETFRAGMENT
similar to those of other cards (the code from cmpci.c was used).
The patch has been tested. Abuse (my favorite linux game) produces
absolutely normal sounds. Actually, it did before. It would be nice to
test this code with something else. Does anybody have a test program?
However, it has been verified that the code in question is actually
executed when Abuse is run.
The patch is also available here:
http://www.red-bean.com/~proski/ymf/ymf_setfrag.diff
Regards,
Pavel Roskin
________________________________
--- linux.orig/drivers/sound/ymfpci.c
+++ linux/drivers/sound/ymfpci.c
@@ -1718,21 +1718,15 @@
case SNDCTL_DSP_SETFRAGMENT:
if (get_user(val, (int *)arg))
return -EFAULT;
- /* P3: these frags are for Doom. Amasingly, it sets [2,2**11]. */
- /* P3 */ // printk("ymfpci: ioctl SNDCTL_DSP_SETFRAGMENT 0x%x\n", val);
-
dmabuf = &state->wpcm.dmabuf;
dmabuf->ossfragshift = val & 0xffff;
dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
- switch (dmabuf->ossmaxfrags) {
- case 1:
- dmabuf->ossfragshift = 12;
- return 0;
- default:
- /* Fragments must be 2K long */
- dmabuf->ossfragshift = 11;
- dmabuf->ossmaxfrags = 2;
- }
+ if (dmabuf->ossfragshift < 4)
+ dmabuf->ossfragshift = 4;
+ if (dmabuf->ossfragshift > 15)
+ dmabuf->ossfragshift = 15;
+ if (dmabuf->ossmaxfrags < 4)
+ dmabuf->ossmaxfrags = 4;
return 0;
case SNDCTL_DSP_GETOSPACE:
________________________________