Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Jul 2000 11:18:07 -0400 (EDT)
From:      mike ryan <msr+fbsd@elision.org>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/20255: [PATCH] resume from suspend breaks pcm
Message-ID:  <20000728151807.C176219316@vapre.elision.org>

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

>Number:         20255
>Category:       kern
>Synopsis:       [PATCH] resume from suspend breaks pcm
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 28 08:20:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     mike ryan
>Release:        FreeBSD 4.1-STABLE i386
>Organization:
>Environment:

	sony vaio z505hs laptop with yamaha ds-1e audio.

>Description:

	after resuming from suspend, sound can no longer be played.  any
	attempt to play sound results in "pcm0: play interrupt timeout,
	channel dead" errors.

>How-To-Repeat:

	suspend + resume.

>Fix:

	this patch works for me:

Index: sys/dev/sound/pci/ds1.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pci/ds1.c,v
retrieving revision 1.8.2.1
diff -c -r1.8.2.1 ds1.c
*** sys/dev/sound/pci/ds1.c	2000/07/19 21:18:45	1.8.2.1
--- sys/dev/sound/pci/ds1.c	2000/07/28 15:05:44
***************
*** 114,119 ****
--- 114,124 ----
  	int		regid, irqid;
  	void		*ih;
  
+ 	u_int32_t	workbase;
+ 	u_int32_t	playctrlbase;
+ 	u_int32_t	recctrlbase;
+ 	u_int32_t	effctrlbase;
+ 
  	u_int32_t *pbase, pbankbase, pbanksize;
  	volatile struct pbank *pbank[2 * 64];
  	volatile struct rbank *rbank;
***************
*** 819,834 ****
  
  	cb = 0;
  	t = buf;
! 	ds_wr(sc, YDSXGR_WORKBASE, sc->ctrlbase + cb, 4);
  	cb += ws;
  	sc->pbase = (u_int32_t *)(t + cb);
  	/* printf("pbase = %p -> 0x%x\n", sc->pbase, sc->ctrlbase + cb); */
! 	ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->ctrlbase + cb, 4);
  	cb += (64 + 1) * 4;
  	sc->rbank = (struct rbank *)(t + cb);
! 	ds_wr(sc, YDSXGR_RECCTRLBASE, sc->ctrlbase + cb, 4);
  	cb += 2 * 2 * rcs;
! 	ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->ctrlbase + cb, 4);
  	cb += 5 * 2 * ecs;
  
  	sc->pbankbase = sc->ctrlbase + cb;
--- 824,843 ----
  
  	cb = 0;
  	t = buf;
! 	sc->workbase = sc->ctrlbase + cb;
! 	ds_wr(sc, YDSXGR_WORKBASE, sc->workbase, 4);
  	cb += ws;
  	sc->pbase = (u_int32_t *)(t + cb);
  	/* printf("pbase = %p -> 0x%x\n", sc->pbase, sc->ctrlbase + cb); */
! 	sc->playctrlbase = sc->ctrlbase + cb;
! 	ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->playctrlbase, 4);
  	cb += (64 + 1) * 4;
  	sc->rbank = (struct rbank *)(t + cb);
! 	sc->recctrlbase = sc->ctrlbase + cb;
! 	ds_wr(sc, YDSXGR_RECCTRLBASE, sc->recctrlbase, 4);
  	cb += 2 * 2 * rcs;
! 	sc->effctrlbase = sc->ctrlbase + cb;
! 	ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->effctrlbase, 4);
  	cb += 5 * 2 * ecs;
  
  	sc->pbankbase = sc->ctrlbase + cb;
***************
*** 970,979 ****
--- 979,1039 ----
  	return ENXIO;
  }
  
+ static int
+ ds_pci_suspend(device_t dev)
+ {
+ 	snddev_info *d = device_get_softc(dev);
+ 	struct sc_info *sc = (struct sc_info *)d->devinfo;
+ 
+ 	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4);
+ 	ds_enadsp(sc, 0);
+ 
+ 	return 0;
+ }
+ 
+ static int
+ ds_pci_resume(device_t dev)
+ {
+ 	int i;
+ 	u_int32_t r;
+ 	snddev_info *d = device_get_softc(dev);
+ 	struct sc_info *sc = (struct sc_info *)d->devinfo;
+ 
+ 	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4);
+ 	ds_enadsp(sc, 0);
+ 	ds_wr(sc, YDSXGR_MODE, 0x00010000, 4);
+ 	ds_wr(sc, YDSXGR_MODE, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_WORKBASE, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_WORKBASE, sc->workbase, 4);
+ 	ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->playctrlbase, 4);
+ 	ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_RECCTRLBASE, sc->recctrlbase, 4);
+ 	ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4);
+ 	ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->effctrlbase, 4);
+ 	r = ds_rd(sc, YDSXGR_GLOBALCTRL, 2);
+ 	ds_wr(sc, YDSXGR_GLOBALCTRL, r & ~0x0007, 2);
+ 
+ 	for (i=0; i < sc->pchn; i++)
+ 		chn_resetbuf(sc->pch[i].channel);
+ 	for (i=0; i < sc->rchn; i++)
+ 		chn_resetbuf(sc->rch[i].channel);
+ 
+ 	ds_enadsp(sc, 1);
+ 	mixer_reinit(d);
+ 	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff, 4);
+ 
+ 	return 0;
+ }
+ 
  static device_method_t ds1_methods[] = {
  	/* Device interface */
  	DEVMETHOD(device_probe,		ds_pci_probe),
  	DEVMETHOD(device_attach,	ds_pci_attach),
+ 	DEVMETHOD(device_suspend,	ds_pci_suspend),
+ 	DEVMETHOD(device_resume,	ds_pci_resume),
  
  	{ 0, 0 }
  };

>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?20000728151807.C176219316>