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>