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: