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>
