Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Aug 2000 21:50:20 -0700 (PDT)
From:      Nick Sayer <nsayer@quack.kfu.com>
To:        freebsd-hackers@freebsd.org
Subject:   ESS Solo users, try this patch
Message-ID:  <200008110450.VAA93536@medusa.kfu.com>

next in thread | raw e-mail | index | archive | help
I believe that sometimes ESS sound chips can give back whacky numbers
under some circumstances when the dma count register is read while DMA
is in progress. I believe this may be a good workaround. I'm considering
applying this, but I'd like it to get some more testing first.

If you have an ESS Solo: Try this and see if recording 16 bit stereo
44100 audio doesn't generate hwptr warnings.

If you have some other ESS chip, see if you can modify the getpos
entry of the applicable driver to do something like this.

In preliminary testing, I've never seen _good_ adjacent reads be more
than 1 number apart, but 16 gives room for slow processors. I've
never seen j have to go past 3 (and past 2 only once in a great while).
If it gets past 1000, then IMHO the DMA count register has become a
pretty good random number generator. :-) The 1000 factor is to avoid
infinite loops if the impossible happens. :-)

--- src/sys/dev/sound/pci/solo.c	2000/08/09 07:14:56	1.8
+++ src/sys/dev/sound/pci/solo.c	2000/08/11 04:43:30
@@ -756,7 +756,7 @@
 static int
 ess_dmapos(struct ess_info *sc, int ch)
 {
-	int p = 0;
+	int p = 0, i, j = 0;
 	u_long flags;
 
 	KASSERT(ch == 1 || ch == 2, ("bad ch"));
@@ -766,11 +766,17 @@
 /*
  * During recording, this register is known to give back
  * garbage if it's not quiescent while being read. That's
- * why we spl, stop the DMA, wait, and be vewy, vewy quiet
+ * why we spl, stop the DMA, and try over and over until
+ * adjacent reads are "close".
  */
 		ess_dmatrigger(sc, ch, 0);
-    		DELAY(20);
-		p = port_rd(sc->vc, 0x4, 2) + 1;
+		do {
+			if (j)
+				printf("DMA count reg bogus: %0x & %0x\n",
+					i, p);
+			i = port_rd(sc->vc, 0x4, 2) + 1;
+			p = port_rd(sc->vc, 0x4, 2) + 1;
+		} while ((i < p || (p - i) > 0x10) && j++ < 1000)
 		ess_dmatrigger(sc, ch, 1);
 	}
 	else if (ch == 2)


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200008110450.VAA93536>