Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 03 Mar 2002 01:53:27 +0900 (JST)
From:      Toshikazu ICHINOSEKI <t.ichinoseki@nifty.com>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/35484: [PATCH] Neomagic sound driver resume problem
Message-ID:  <20020303.015327.74757502.t.ichinoseki@nifty.com>

next in thread | raw e-mail | index | archive | help

>Number:         35484
>Category:       kern
>Synopsis:       [PATCH] Neomagic sound driver resume problem
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 02 09:10:02 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Toshikazu Ichinoseki
>Release:        FreeBSD 4.5-STABLE i386
>Organization:
>Environment:
System: FreeBSD capella 4.5-STABLE FreeBSD 4.5-STABLE #0: Sat Feb 23 00:38:24 JST 2002 toshi@capella:/usr/src/sys/compile/CAPELLA i386

Machine: Panasonic Let's note CF-M2EV
		 (Celeron-550MHz, 440BX, 128MB Mem,
		  NeoMagic NM2200 graphics/sound chip (MagicMedia 256AV))
	
>Description:
	After I applied patch of problem report kern/35230 which I had
	sent, one more problem is reported in Freebsd-users-jp ML.
	The problem is that the periodic noise is generated while playing
	music after resuming once running X.

	After I applied attached patch-1, I got following on boot -v:

	---------- pcm0 part of dmesg ---------------
	pcm0: <NeoMagic 256AV> mem 0xdd300000-0xdd3fffff,0xddc00000-0xddffffff irq 10 at device 0.1 on pci1
	pcm0: buftop is 0x0027ec00                <=== *1
	pcm0: buftop is changed to 0x0027e800     <=== *2
	pcm0: ac97 codec id 0x83847609 (SigmaTel STAC9721/9723)
	pcm0: ac97 codec features 18 bit DAC, 18 bit ADC, 5 bit master volume, SigmaTel 3D Enhancement
	pcm0: ac97 primary codec extended features AMAP
	pcm0: rec buf 0xc8583800
	pcm0: play buf 0xc857f800
	---------- pcm0 part of dmesg ---------------

	This means that buftop is set to 0x0027ec00 first then changed to
	0x0027e800 in nm_init() by detecting magic number in buffer. The
	playing buffer and the recording buffer of both driver and
	channel are set to relative value against buftop (== 0x0027e800)
	on boot. However I get *1 line only on resuming after running X
	then suspending. Probably X destroys magic number in buffer, and
	driver is not able to detect it on resuming. So the playing buffer
	and the recording buffer of driver are re-set the relative values
	of new buftop 0x0027ec00, but channel keeps old values. The result
	of this, the playing buffer of driver becomes to shift 1KB from
	channel's and keeps 1kB garbage data which generates periodic
	noise while playing music.

>How-To-Repeat:
	Every time after resuming once running X.

>Fix:
	Attached patch-2 prevents changing buftop on resuming. I think it
	is not needed to re-set buffers on resuming. After applying
	patch-2, my CF-M2EV plays music fine even though I run X, suspend
	and then resume.
	I have received a report that this patch-2 fixes same problem on
	another note-pc (panasonic Let's note CF-M2XR) in FreeBSD-users-jp
	ML.
	  
--------------- patch-1 for checking -----------------------------
--- neomagic.c.old	Mon Feb 25 00:40:34 2002
+++ neomagic.c	Mon Feb 25 21:56:28 2002
@@ -558,10 +558,15 @@
 	ofs = sc->buftop - 0x0400;
 	sc->buftop -= 0x1400;
 
+	if (bootverbose)
+		device_printf(sc->dev, "buftop is 0x%08x\n", sc->buftop);
  	if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) {
 		i = nm_rdbuf(sc, ofs + 4, 4);
-		if (i != 0 && i != 0xffffffff)
+		if (i != 0 && i != 0xffffffff) {
+			if (bootverbose)
+				device_printf(sc->dev, "buftop is changed to 0x%08x\n", i);
 			sc->buftop = i;
+		}
 	}
 
 	sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
-------------------------------------------------------------------

--------------- patch-2 to fix problem ----------------------------
--- neomagic.c.old	Mon Feb 25 00:40:34 2002
+++ neomagic.c	Mon Feb 25 21:56:28 2002
@@ -766,11 +771,17 @@
 
 	sc = pcm_getdevinfo(dev);
 
-	/* Reinit audio device */
-    	if (nm_init(sc) == -1) {
-		device_printf(dev, "unable to reinitialize the card\n");
-		return ENXIO;
-	}
+	/*
+	 * Reinit audio device.
+	 * Don't call nm_init(). It would change buftop if X ran or
+	 * is running. This makes playing and recording buffer address
+	 * shift but these buffers of channel layer are not changed.
+	 * As a result of this inconsistency, periodic noise will be
+	 * generated while playing.
+	 */
+	nm_wr(sc, 0, 0x11, 1);
+	nm_wr(sc, 0x214, 0, 2);
+
 	/* Reinit mixer */
     	if (mixer_reinit(dev) == -1) {
 		device_printf(dev, "unable to reinitialize the mixer\n");
-------------------------------------------------------------------
>Release-Note:
>Audit-Trail:
>Unformatted:

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




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