So the patch below specifically enables VRA during rate 
change requests (based on code from Jim Studt, posted to LKML on Dec
29).  This
is needed for things like Real Player to work , because the first thing
RealPlayer 
does is to set the DAC rate to 44100Hz.
Also, the patch already in 2.4.0.-prerelease introduced a bug in the
driver that we 
get a divide-by-zero error if we just do "fd=open("/dev/dsp", O_WRONLY)
; close (fd);".  
This is also fixed below (the last hunk).
--- linux/drivers/sound/i810_audio.c.old        Sat Dec 30 13:23:14 2000
+++ linux/drivers/sound/i810_audio.c    Mon Jan  1 13:24:36 2001
@@ -383,6 +383,7 @@
 {
        struct dmabuf *dmabuf = &state->dmabuf;
        u32 dacp;
+       u16 extended_status;
        struct ac97_codec *codec=state->card->ac97_codec[0];
        if(!(state->card->ac97_features&0x0001))
@@ -410,6 +411,10 @@
        if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
        {
+               /* Reset variable rate mode */
+               extended_status = i810_ac97_get(codec,
AC97_EXTENDED_STATUS);
                i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
@@ -433,6 +438,7 @@
 {
        struct dmabuf *dmabuf = &state->dmabuf;
        u32 dacp;
+       u16 extended_status;
        struct ac97_codec *codec=state->card->ac97_codec[0];
 
        if(!(state->card->ac97_features&0x0001))
@@ -460,6 +466,10 @@
 
        if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
        {
+               /* Reset variable rate mode */
+               extended_status = i810_ac97_get(codec,
AC97_EXTENDED_STATUS);
+               if (!(extended_status&1))
+                       i810_ac97_set(codec, AC97_EXTENDED_STATUS,
extended_status|1);
                /* Power down the ADC */
                dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
                i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
@@ -770,7 +780,10 @@
        swptr = dmabuf->swptr;
        spin_unlock_irqrestore(&state->card->lock, flags);
 
-       len = swptr % (dmabuf->dmasize/SG_LEN);
+       if (dmabuf->dmasize)
+               len = swptr % (dmabuf->dmasize/SG_LEN);
+       else
+               len = 0;
 
        memset(dmabuf->rawbuf + swptr, silence, len);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/