Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jul 2006 17:40:21 GMT
From:      Cy Schubert <Cy.Schubert@spqr.komquats.com>
To:        freebsd-acpi@FreeBSD.org
Subject:   Re: kern/98171: [acpi] ACPI 1304 / 0501 errors on Acer 5024WLMi Laptop (probably on all 3020 / 5020 series)
Message-ID:  <200607151740.k6FHeL4o046479@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/98171; it has been noted by GNATS.

From: Cy Schubert <Cy.Schubert@komquats.com>
To: bug-followup <bug-followup@freebsd.org>, William.Anderle@Alice.it
Cc: njl@freebsd.org
Subject: Re: kern/98171: [acpi] ACPI 1304 / 0501 errors on Acer 5024WLMi
 Laptop (probably on all 3020 / 5020 series)
Date: Sat, 15 Jul 2006 10:32:11 -0700

 I tried a couple of things. First, I enabled the EC burst mode code in 
 acpi_ec.c, via a kernel tunable, hw.acpi.ec.burst=1 in the patch below. 
 That solved the messages problem however it caused the battery status to 
 stop working completely -- prior to the patch it worked about half the 
 time. Thinking that a 10 ms polling loop may inundate the embedded 
 controller that monitors battery status and temperature in the ACER Aspire 
 notebooks, I turned the poll delay also into a kernel tunable, 
 hw.apci.ec.poll_delay. Normally the poll delay is 10 ms, however IMHO 
 polling for battery and temperature status, along with anything else the 
 embedded controller monitors, every second is probably good enough. That 
 seems to have fixed the problem. The messages are now gone and battery 
 status is reported 100% of the time.
 
 You will need to apply the following patch:
 
 --- sys/dev/acpica/acpi_ec.c.orig	Thu May 11 10:41:00 2006
 +++ sys/dev/acpica/acpi_ec.c	Sat Jul 15 09:47:27 2006
 @@ -291,6 +291,12 @@
  static int	ec_poll_timeout = EC_POLL_TIMEOUT;
  TUNABLE_INT("hw.acpi.ec.poll_timeout", &ec_poll_timeout);
  
 +static int	ec_poll_delay = EC_POLL_DELAY;
 +TUNABLE_INT("hw.acpi.ec.poll_delay", &ec_poll_delay);
 +
 +static int ec_burst = 0;
 +TUNABLE_INT("hw.acpi.ec.burst", &ec_burst);
 +
  ACPI_SERIAL_DECL(ec, "ACPI embedded controller");
  
  static __inline ACPI_STATUS
 @@ -875,15 +881,15 @@
       * Poll the EC status register for up to 1 ms in chunks of 10 us 
       * to detect completion of the last command.
       */
 -    for (i = 0; i < 1000 / EC_POLL_DELAY; i++) {
 +    for (i = 0; i < 1000 / ec_poll_delay; i++) {
  	EcStatus = EC_GET_CSR(sc);
  	if (EVENT_READY(Event, EcStatus)) {
  	    Status = AE_OK;
  	    break;
  	}
 -	AcpiOsStall(EC_POLL_DELAY);
 +	AcpiOsStall(ec_poll_delay);
      }
 -    period = i * EC_POLL_DELAY;
 +    period = i * ec_poll_delay;
  
      /*
       * If we still don't have a response and we're up and running, wait up
 @@ -966,10 +972,10 @@
      ACPI_SERIAL_ASSERT(ec);
      CTR1(KTR_ACPI, "ec read from %#x", Address);
  
 -#ifdef notyet
 -    /* If we can't start burst mode, continue anyway. */
 -    EcCommand(sc, EC_COMMAND_BURST_ENABLE);
 -#endif
 +    if (ec_burst != 0) {
 +	/* If we can't start burst mode, continue anyway. */
 +	EcCommand(sc, EC_COMMAND_BURST_ENABLE);
 +    }
  
      Status = EcCommand(sc, EC_COMMAND_READ);
      if (ACPI_FAILURE(Status))
 @@ -985,13 +991,11 @@
  
      *Data = EC_GET_DATA(sc);
  
 -#ifdef notyet
 -    if (sc->ec_burstactive) {
 +    if (ec_burst != 0) {
  	Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
  	if (ACPI_FAILURE(Status))
  	    return (Status);
      }
 -#endif
  
      return (AE_OK);
  }    
 @@ -1004,10 +1008,10 @@
      ACPI_SERIAL_ASSERT(ec);
      CTR2(KTR_ACPI, "ec write to %#x, data %#x", Address, *Data);
  
 -#ifdef notyet
 -    /* If we can't start burst mode, continue anyway. */
 -    EcCommand(sc, EC_COMMAND_BURST_ENABLE);
 -#endif
 +    if (ec_burst != 0) {
 +	/* If we can't start burst mode, continue anyway. */
 +	EcCommand(sc, EC_COMMAND_BURST_ENABLE);
 +    }
  
      Status = EcCommand(sc, EC_COMMAND_WRITE);
      if (ACPI_FAILURE(Status))
 @@ -1029,13 +1033,11 @@
  	return (Status);
      }
  
 -#ifdef notyet
 -    if (sc->ec_burstactive) {
 +    if (ec_burst != 0) {
  	Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
  	if (ACPI_FAILURE(Status))
  	    return (Status);
      }
 -#endif
  
      return (AE_OK);
  }
 
 After you apply the patch, rebuild and install the new kernel. Then add the 
 following to your loader.conf file:
 
 #hw.acpi.ec.poll_timeout=100
 #hw.acpi.ec.poll_delay=10
 hw.acpi.ec.poll_delay=1000
 # hw.acpi.ec.burst=1
 
 You may have to play with these a bit to get them just right. I'm thinking 
 of making these sysctl variables too so you can adjust them on the fly, 
 however given that each time the kernel polls for a sysctl variable, CPU 
 time is used, slowing down the system ever so slightly, I'm kind of leaning 
 toward just keeping them as kernel tunables to be set at boot time only. 
 (Maybe the sysctl variables could be set when a debug kernel tunable is set 
 at boot time, allowing the user to adjust the settings more quickly without 
 rebooting, then set them in loader.conf but that should really be a matter 
 of discussion on freebsd-arch or hackers.) Anyhow, this solved the problem 
 I had on my ACER Aspire 3623NWXMi. You may want to try different 
 combinations of the above kernel tunables.
 
 As I'm a ports commmitter I need to find a src committer to commit this for 
 me.
 
 
 -- 
 Cheers,
 Cy Schubert <Cy.Schubert@komquats.com>
 FreeBSD UNIX:  <cy@FreeBSD.org>   Web:  http://www.FreeBSD.org
 
 			e**(i*pi)+1=0
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607151740.k6FHeL4o046479>