2005-01-17 18:45:31

by John W. Linville

[permalink] [raw]
Subject: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

"Some" OSS applications have trouble with later versions of the
i810_audio driver. Wolfenstein Enemy Territory from idSoftware is
one such application.

I did a little legwork in BK and tracked-down the exact change which
caused the break. The changelog comments are dismissive to the
original code. However, I find that recreating a patch equivalent
to what was removed restores sound to the game.

Anyone have any suggestions for a patch that a) works; and, b)
accounts for the concerns expressed in the changelog?

John

P.S. Here is the problematic patch: (DO NOT TRY TO APPLY THIS)

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/05/11 03:51:54-04:00 [email protected]
# [sound i810] remove bogus CIV_TO_LVI
#
# This patch removes a pair of bogus LVI assignments. The explanation in
# the comment is wrong because the value of PCIB tells the hardware that
# the DMA buffer can be processed even if LVI == CIV.
#
# Setting LVI to CIV + 1 causes overruns when with short writes
# (something that vmware is very fond of).
#
# drivers/sound/i810_audio.c
# 2004/05/11 03:51:52-04:00 [email protected] +0 -10
# [sound i810] remove bogus CIV_TO_LVI
#
# This patch removes a pair of bogus LVI assignments. The explanation in
# the comment is wrong because the value of PCIB tells the hardware that
# the DMA buffer can be processed even if LVI == CIV.
#
# Setting LVI to CIV + 1 causes overruns when with short writes
# (something that vmware is very fond of).
#
diff -Nru a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c
--- a/drivers/sound/i810_audio.c 2005-01-14 16:20:27 -05:00
+++ b/drivers/sound/i810_audio.c 2005-01-14 16:20:27 -05:00
@@ -1079,25 +1079,15 @@
else
port += dmabuf->write_channel->port;

- /* if we are currently stopped, then our CIV is actually set to our
- * *last* sg segment and we are ready to wrap to the next. However,
- * if we set our LVI to the last sg segment, then it won't wrap to
- * the next sg segment, it won't even get a start. So, instead, when
- * we are stopped, we set both the LVI value and also we increment
- * the CIV value to the next sg segment to be played so that when
- * we call start_{dac,adc}, things will operate properly
- */
if (!dmabuf->enable && dmabuf->ready) {
if(rec && dmabuf->count < dmabuf->dmasize &&
(dmabuf->trigger & PCM_ENABLE_INPUT))
{
- CIV_TO_LVI(port, 1);
__start_adc(state);
while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
} else if (!rec && dmabuf->count &&
(dmabuf->trigger & PCM_ENABLE_OUTPUT))
{
- CIV_TO_LVI(port, 1);
__start_dac(state);
while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
}
--
John W. Linville
[email protected]


2005-01-17 18:46:43

by John W. Linville

[permalink] [raw]
Subject: [patch 2.4.29-rc1] i810_audio: offset LVI from CIV to avoid stalled start

Offset LVI past CIV when starting DAC/ADC in order to prevent
stalled start.
---
Here is the (working) patch I'm using against a later 2.4. This makes
sound work fine with Enemy Territory.

drivers/sound/i810_audio.c | 10 ++++++++++
1 files changed, 10 insertions(+)

--- linux-test/drivers/sound/i810_audio.c.orig 2005-01-14 17:21:20.000000000 -0500
+++ linux-test/drivers/sound/i810_audio.c 2005-01-17 13:11:31.000000000 -0500
@@ -1081,10 +1081,20 @@ static void __i810_update_lvi(struct i81
if (count < fragsize)
return;

+ /* if we are currently stopped, then our CIV is actually set to our
+ * *last* sg segment and we are ready to wrap to the next. However,
+ * if we set our LVI to the last sg segment, then it won't wrap to
+ * the next sg segment, it won't even get a start. So, instead, when
+ * we are stopped, we set both the LVI value and also we increment
+ * the CIV value to the next sg segment to be played so that when
+ * we call start, things will operate properly
+ */
if (!dmabuf->enable && dmabuf->ready) {
if (!(dmabuf->trigger & trigger))
return;

+ CIV_TO_LVI(state->card, port, 1);
+
start(state);
while (!(I810_IOREADB(state->card, port + OFF_CR) & ((1<<4) | (1<<2))))
;

2005-01-17 20:43:45

by Herbert Xu

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Mon, Jan 17, 2005 at 01:37:08PM -0500, John W. Linville wrote:
> "Some" OSS applications have trouble with later versions of the
> i810_audio driver. Wolfenstein Enemy Territory from idSoftware is
> one such application.

Would it be possible to create a minimal program (something that triggers
a start through __i810_update_lvi) that reproduces this problem?

Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2005-01-17 21:45:42

by John W. Linville

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Tue, Jan 18, 2005 at 07:39:30AM +1100, Herbert Xu wrote:
> On Mon, Jan 17, 2005 at 01:37:08PM -0500, John W. Linville wrote:
> > "Some" OSS applications have trouble with later versions of the
> > i810_audio driver. Wolfenstein Enemy Territory from idSoftware is
> > one such application.
>
> Would it be possible to create a minimal program (something that triggers
> a start through __i810_update_lvi) that reproduces this problem?

Possible is, of course, somewhat relative... :-) I'm not immediately
equipped to produce such a program.

Enemy Territory is available for free (as in beer) download from
http://www.enemy-territory.com. Sound plays almost immediately once the
game is started.

Is this sufficient?

John
--
John W. Linville
[email protected]

2005-01-17 22:59:45

by Thomas Voegtle

[permalink] [raw]
Subject: Re: [patch 2.4.29-rc1] i810_audio: offset LVI from CIV to avoid stalled start

On Mon, 17 Jan 2005, John W. Linville wrote:

> Offset LVI past CIV when starting DAC/ADC in order to prevent
> stalled start.
> ---
> Here is the (working) patch I'm using against a later 2.4. This makes
> sound work fine with Enemy Territory.
>

This patch, hand-modified for 2.6.10 enabled sound again with i810 and
quake3. (Q3 1.32b linux-i386 Nov 14 2002)

The problem was that in the opening of quake3 sound was there and then
suddenly the sound stopped.

Thank you John for tracking down this problem.


Thomas

--
Thomas V?gtle email: [email protected]
----- http://www.voegtle-clan.de/thomas ------

2005-01-17 23:33:16

by Herbert Xu

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Mon, Jan 17, 2005 at 04:44:22PM -0500, John W. Linville wrote:
>
> Enemy Territory is available for free (as in beer) download from
> http://www.enemy-territory.com. Sound plays almost immediately once the
> game is started.
>
> Is this sufficient?

Sure, I don't mind trying it out :)

In the mean time, does this patch fix your problem as well?

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Attachments:
(No filename) (565.00 B)
p (867.00 B)
Download all attachments

2005-01-18 18:08:21

by John W. Linville

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Tue, Jan 18, 2005 at 10:23:23AM +1100, Herbert Xu wrote:
> On Mon, Jan 17, 2005 at 04:44:22PM -0500, John W. Linville wrote:
> >
> > Enemy Territory is available for free (as in beer) download from

> Sure, I don't mind trying it out :)
>
> In the mean time, does this patch fix your problem as well?

Herbert,

No, that does not fix it. :-( In fact, it doesn't seem to alter the
problem at all...

John
--
John W. Linville
[email protected]

2005-01-18 22:45:06

by Herbert Xu

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Tue, Jan 18, 2005 at 01:07:47PM -0500, John W. Linville wrote:
>
> No, that does not fix it. :-( In fact, it doesn't seem to alter the
> problem at all...

OK. In that case I agree with your patch. The overruns that I
attributed to it were probably caused by other bugs that's been
fixed since.

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2005-01-19 09:03:34

by Thomas Voegtle

[permalink] [raw]
Subject: Re: [rfc] i810_audio: offset LVI from CIV to avoid stalled start

On Wed, 19 Jan 2005, Herbert Xu wrote:

> On Tue, Jan 18, 2005 at 01:07:47PM -0500, John W. Linville wrote:
> >
> > No, that does not fix it. :-( In fact, it doesn't seem to alter the
> > problem at all...
>
> OK. In that case I agree with your patch. The overruns that I
> attributed to it were probably caused by other bugs that's been
> fixed since.
>
> Cheers,
>


Here is the same patch against 2.6.11-rc1-bk6. Works for me.


--- linux-2.6.11-rc1-bk6/sound/oss/i810_audio.c.old 2005-01-19 09:47:20.438345600 +0100
+++ linux-2.6.11-rc1-bk6/sound/oss/i810_audio.c 2005-01-19 09:48:43.618700264 +0100
@@ -1196,10 +1196,20 @@
if (count < fragsize)
return;

+ /* if we are currently stopped, then our CIV is actually set to our
+ * *last* sg segment and we are ready to wrap to the next. However,
+ * if we set our LVI to the last sg segment, then it won't wrap to
+ * the next sg segment, it won't even get a start. So, instead, when
+ * we are stopped, we set both the LVI value and also we increment
+ * the CIV value to the next sg segment to be played so that when
+ * we call start, things will operate properly
+ */
if (!dmabuf->enable && dmabuf->ready) {
if (!(dmabuf->trigger & trigger))
return;

+ CIV_TO_LVI(state->card, port, 1);
+
start(state);
while (!(I810_IOREADB(state->card, port + OFF_CR) & ((1<<4) | (1<<2))))
;






--
Thomas V?gtle email: [email protected]
----- http://www.voegtle-clan.de/thomas ------