Subject: kern/11738: auich(4) play audio hung up after resume time.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <takkun@mma.club.uec.ac.jp>
List: netbsd-bugs
Date: 12/14/2000 07:55:17
>Number: 11738
>Category: kern
>Synopsis: auich(4) play audio hung up after resume time.
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Dec 14 07:55:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: IIMURA Takuji
>Release: 1.5
>Organization:
University of Electro Communications
>Environment:
NetBSD polar 1.5 NetBSD 1.5 (KUMA) #18: Thu Dec 14 23:49:19 JST 2000 uirou@polar:/usr/src/sys/arch/i386/compile/KUMA i386
>Description:
auich(4) audio driver have no recover program code for resume time. (e.g. laptop machine)
If play audio after resume, kernel hung up.
>How-To-Repeat:
NONE.
>Fix:
I have quick hack patch for src/sys/dev/pci/auich.c. Please test this.
(I refer to cs4280.c cs4280_power() function)
But I test in NetBSD-1.5 source tree with auich.c.
I hope this patch is correct.
*** auich.c.1.1 Fri Dec 15 00:07:49 2000
--- auich.c Fri Dec 15 00:07:57 2000
***************
*** 100,105 ****
--- 101,107 ----
#include <machine/bus.h>
+ #include <dev/ic/ac97reg.h>
#include <dev/ic/ac97var.h>
struct auich_dma {
***************
*** 169,174 ****
--- 171,179 ----
void (*sc_rintr)(void *);
void *sc_rarg;
+
+ char sc_suspend;
+ void *sc_powerhook; /* Power Hook */
};
/* Debug */
***************
*** 251,256 ****
--- 256,262 ----
int auich_read_codec(void *, u_int8_t, u_int16_t *);
int auich_write_codec(void *, u_int8_t, u_int16_t);
void auich_reset_codec(void *);
+ void auich_power __P((int, void *));
static const struct auich_devtype {
int product;
***************
*** 362,367 ****
--- 368,377 ----
DPRINTF(ICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n",
sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici));
+ /* resume handler set */
+ sc->sc_suspend = PWR_RESUME;
+ sc->sc_powerhook = powerhook_establish(auich_power, sc);
+
/* Reset codec and AC'97 */
auich_reset_codec(sc);
***************
*** 432,437 ****
--- 442,471 ----
}
void
+ auich_power(int why, void *v)
+ {
+ struct auich_softc *sc = v;
+
+ /*printf("%s: auich_power why=%d\n",
+ sc->sc_dev.dv_xname, why);*/
+
+ if(why != PWR_RESUME){
+ sc->sc_suspend = why;
+ auich_close(sc);
+ /* should I powerdown here ? */
+ /*auich_write_codec(sc, AC97_REG_POWER, ICH_POWER_DOWN_ALL);*/
+ }else{
+ if(sc->sc_suspend == PWR_RESUME) {
+ printf("auich_power: odd, resume without suspend.\n");
+ sc->sc_suspend = why;
+ return;
+ }
+ auich_reset_codec(sc);
+ sc->codec_if->vtbl->restore_ports(sc->codec_if);
+ }
+ }
+
+ void
auich_reset_codec(void *v)
{
struct auich_softc *sc = v;
>Release-Note:
>Audit-Trail:
>Unformatted: