Re: Problem with snd_ich.ko

From: Don Lewis <truckman_at_FreeBSD.org>
Date: Sun, 12 Sep 2004 18:30:19 -0700 (PDT)
On 12 Sep, Derrick Edwards wrote:
> On Friday 10 September 2004 10:24 am, Lutz Bichler wrote:
> 
> Did you ever get an answer to yoru problem? I kinda was having the same 
> problem. When booting up, I would be able to get sound wihen I play songs 
> from the console. When I booted into kde 3.3 during the splash sreen I would 
> lose the sound. If I want to have sound during the kde session I have to wait 
> until kde is up and running then load snd_ich. If  I log out of that current 
> session I have to reboot and start the process all over.. 
> Derrick
> 
>> Hi,
>>
>> i have a "funny" problem with snd_ich on 5.3 Beta3. Whenever i boot my
>> machine, sound.ko and snd_ich.ko are loaded, but i do not get any sound
>> working. After unloading and reloading snd_ich.ko things work fine. Any
>> idea abou what going wrong at boot-time loading of the modules?

You might want to try this patch:

Index: sys/dev/sound/pcm/channel.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pcm/channel.c,v
retrieving revision 1.97
diff -u -r1.97 channel.c
--- sys/dev/sound/pcm/channel.c	28 Feb 2004 19:47:02 -0000	1.97
+++ sys/dev/sound/pcm/channel.c	9 Sep 2004 20:41:18 -0000
_at__at_ -405,9 +405,9 _at__at_
 
 	if ((c->flags & CHN_F_MAPPED) || !(c->flags & CHN_F_TRIGGERED))
 		return;
-	chn_trigger(c, PCMTRIG_EMLDMARD);
 	chn_dmaupdate(c);
 	ret = chn_rdfeed(c);
+	chn_trigger(c, PCMTRIG_EMLDMARD);
 	if (ret)
 		printf("chn_rdfeed: %d\n", ret);
 
_at__at_ -417,15 +417,21 _at__at_
 static void
 chn_rdintr(struct pcm_channel *c)
 {
-	int ret;
 
 	CHN_LOCKASSERT(c);
 	/* tell the driver to update the primary buffer if non-dma */
-	chn_trigger(c, PCMTRIG_EMLDMARD);
 	/* update pointers in primary buffer */
 	chn_dmaupdate(c);
 	/* ...and feed from primary to secondary */
-	ret = chn_rdfeed(c);
+	chn_rdfeed(c);
+	chn_trigger(c, PCMTRIG_EMLDMARD);
+}
+
+int
+chn_hwunownedbufoffset(struct pcm_channel *c)
+{
+	return ((c->direction == PCMDIR_PLAY) ? sndbuf_getfreeptr(c->bufhard) :
+	    sndbuf_getreadyptr(c->bufhard));
 }
 
 /*
Index: sys/dev/sound/pcm/channel.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pcm/channel.h,v
retrieving revision 1.30
diff -u -r1.30 channel.h
--- sys/dev/sound/pcm/channel.h	28 Feb 2004 19:47:02 -0000	1.30
+++ sys/dev/sound/pcm/channel.h	9 Sep 2004 20:36:34 -0000
_at__at_ -93,6 +93,7 _at__at_
 void chn_intr(struct pcm_channel *c);
 int chn_wrfeed(struct pcm_channel *c);
 int chn_rdfeed(struct pcm_channel *c);
+int chn_hwunownedbufoffset(struct pcm_channel *c);
 int chn_abort(struct pcm_channel *c);
 
 void chn_wrupdate(struct pcm_channel *c);
Index: sys/dev/sound/pci/ich.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pci/ich.c,v
retrieving revision 1.42
diff -u -r1.42 ich.c
--- sys/dev/sound/pci/ich.c	16 Jul 2004 03:59:27 -0000	1.42
+++ sys/dev/sound/pci/ich.c	9 Sep 2004 20:36:10 -0000
_at__at_ -336,11 +336,33 _at__at_
 {
 	struct sc_chinfo *ch = data;
 	struct sc_info *sc = ch->parent;
+	u_int32_t lbb, lbi, lvi, nlbi;
 
 	switch (go) {
 	case PCMTRIG_START:
 		ch->run = 1;
 		ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)(ch->desc_addr), 4);
+		lvi = ((chn_hwunownedbufoffset(ch->channel) +
+		    ch->blkcnt * ch->blksz - 1) / ch->blksz) % ch->blkcnt;
+		ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
+		ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1);
+		break;
+
+	case PCMTRIG_EMLDMAWR:
+	case PCMTRIG_EMLDMARD:
+		lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1);
+		lbi = lvi % ch->blkcnt;
+		lbb = lvi / ch->blkcnt;
+		nlbi = ((chn_hwunownedbufoffset(ch->channel) +
+		    ch->blkcnt * ch->blksz - 1) / ch->blksz) % ch->blkcnt;
+		nlbi = (chn_hwunownedbufoffset(ch->channel) / ch->blksz +
+		    ch->blkcnt - 1) % ch->blkcnt;
+		if (nlbi < lbi)
+			lbb = (lbb + 1) % (ICH_DTBL_LENGTH / ch->blkcnt);
+		lvi = lbb * ch->blkcnt + nlbi;
+		ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
+		/* restart channel in case DMA underflowed and shut down */
+		/* XXX - track restarts? */
 		ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1);
 		break;
 
_at__at_ -394,7 +416,7 _at__at_
 {
 	struct sc_info *sc = (struct sc_info *)p;
 	struct sc_chinfo *ch;
-	u_int32_t cbi, lbi, lvi, st, gs;
+	u_int32_t st, gs;
 	int i;
 
 	gs = ich_rd(sc, ICH_REG_GLOB_STA, 4) & ICH_GLOB_STA_IMASK;
_at__at_ -417,20 +439,6 _at__at_
 				/* block complete - update buffer */
 			if (ch->run)
 				chn_intr(ch->channel);
-			lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1);
-			cbi = ch->civ % ch->blkcnt;
-			if (cbi == 0)
-				cbi = ch->blkcnt - 1;
-			else
-				cbi--;
-			lbi = lvi % ch->blkcnt;
-			if (cbi >= lbi)
-				lvi += cbi - lbi;
-			else
-				lvi += cbi + ch->blkcnt - lbi;
-			lvi %= ICH_DTBL_LENGTH;
-			ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
-
 		}
 		/* clear status bit */
 		ich_wr(sc, ch->regbase +
Received on Sun Sep 12 2004 - 23:30:28 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:11 UTC