Date: Thu, 16 Jul 2009 09:59:32 +0200 From: David Naylor <naylor.b.david@gmail.com> To: eculp <eculp@encontacto.net> Cc: freebsd-current <freebsd-current@freebsd.org> Subject: Re: Acer Laptop overheating with ACPI error that I don't understand. Message-ID: <200907160959.37024.naylor.b.david@gmail.com> In-Reply-To: <20090714183503.165415zfkagwfb5w@econet.encontacto.net> References: <20090714183503.165415zfkagwfb5w@econet.encontacto.net>
next in thread | previous in thread | raw e-mail | index | archive | help
--nextPart2225410.334euvKaTl Content-Type: multipart/mixed; boundary="Boundary-01=_k3tXK33FiTl0Q0d" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_k3tXK33FiTl0Q0d Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Wednesday 15 July 2009 01:35:03 eculp wrote: > I am having overheating problems with my Acer Aspire laptop. > # uname -a > FreeBSD ed.local.net.mx 8.0-BETA1 FreeBSD 8.0-BETA1 #256: Thu Jul 9 > 07:05:20 CDT 2009 > root@ed.local.net.mx:/usr/obj/usr/src/sys/ENCONTACTO i386 > > I've been having this problem for several months and compensating by > reducing dev.cpu.0.freq from 1900 to 1200 and 800 in warm offices. > > The errors I'm seeing in the log files are: > > +acpi_ec0: EcRead: failed waiting to get data > +ACPI Exception: AE_NO_HARDWARE_RESPONSE, Returned by Handler for > [EmbeddedControl] 20090521 evregion-531 > +ACPI Error (psparse-0633): Method parse/execution failed > [\\_TZ_.THRM._TMP] (Node 0xc4e75960), AE_NO_HARDWARE_RESPONSE > > I'm afraid that I don't understand them. > > Any suggestions appreciated, > > ed A similar problem has been discussed on freebsd-acpi@. A patch was created= =20 that *may* help you. Here are some of the links: Start of discussion: http://markmail.org/message/oervuwnjmfmyqwxi Second patch: http://markmail.org/message/yvd523kg5blvhhab And attached for the second patch (these mail readers just love eating my=20 homework :) ) Good luck, David --Boundary-01=_k3tXK33FiTl0Q0d Content-Type: text/x-diff; charset="iso 8859-15"; name="acpi_ec.c.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="acpi_ec.c.diff" =2D-- acpi_ec.c~ 2009-06-17 21:14:48.000000000 +0200 +++ acpi_ec.c 2009-06-19 14:40:02.000000000 +0200 @@ -168,7 +168,7 @@ #define EC_LOCK_TIMEOUT 1000 =20 /* Default delay in microseconds between each run of the status polling lo= op. */ =2D#define EC_POLL_DELAY 5 +#define EC_POLL_DELAY 100 =20 /* Total time in ms spent waiting for a response from EC. */ #define EC_TIMEOUT 750 @@ -184,13 +184,21 @@ SYSCTL_DECL(_debug_acpi); SYSCTL_NODE(_debug_acpi, OID_AUTO, ec, CTLFLAG_RD, NULL, "EC debugging"); =20 =2Dstatic int ec_burst_mode; +static int ec_burst_mode =3D FALSE; TUNABLE_INT("debug.acpi.ec.burst", &ec_burst_mode); =2DSYSCTL_INT(_debug_acpi_ec, OID_AUTO, burst, CTLFLAG_RW, &ec_burst_mode, = 0, +SYSCTL_INT(_debug_acpi_ec, OID_AUTO, burst, CTLFLAG_RW, &ec_burst_mode, FA= LSE, "Enable use of burst mode (faster for nearly all systems)"); =2Dstatic int ec_polled_mode; +static int ec_delay =3D 0; +TUNABLE_INT("debug.acpi.ec.delay", &ec_delay); +SYSCTL_INT(_debug_acpi_ec, OID_AUTO, delay, CTLFLAG_RW, &ec_delay, 0, + "Delay after waiting for responce (GPE and polled mode)"); +static int ec_gpe_mode =3D FALSE; +TUNABLE_INT("debug.acpi.ec.gpe", &ec_gpe_mode); +SYSCTL_INT(_debug_acpi_ec, OID_AUTO, gpe, CTLFLAG_RW, &ec_gpe_mode, FALSE, + "Disable adaptive GPE switching (to polled mode)"); +static int ec_polled_mode =3D FALSE; TUNABLE_INT("debug.acpi.ec.polled", &ec_polled_mode); =2DSYSCTL_INT(_debug_acpi_ec, OID_AUTO, polled, CTLFLAG_RW, &ec_polled_mode= , 0, +SYSCTL_INT(_debug_acpi_ec, OID_AUTO, polled, CTLFLAG_RW, &ec_polled_mode, = =46ALSE, "Force use of polled mode (only if interrupt mode doesn't work)"); static int ec_timeout =3D EC_TIMEOUT; TUNABLE_INT("debug.acpi.ec.timeout", &ec_timeout); @@ -794,6 +802,7 @@ EC_STATUS ec_status; =20 status =3D AE_NO_HARDWARE_RESPONSE; + ec_status =3D EC_GET_CSR(sc); if (sc->ec_burstactive && !(ec_status & EC_FLAG_BURST_MODE)) { CTR1(KTR_ACPI, "ec burst disabled in waitevent (%s)", msg); @@ -810,56 +819,36 @@ EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event, u_int gen_count) { ACPI_STATUS Status; =2D int count, i, slp_ival; + int count, i, req_ticks, cur_ticks; =20 ACPI_SERIAL_ASSERT(ec); Status =3D AE_NO_HARDWARE_RESPONSE; int need_poll =3D cold || rebooting || ec_polled_mode || sc->ec_suspen= ding; =2D /* =2D * The main CPU should be much faster than the EC. So the status sh= ould =2D * be "not ready" when we start waiting. But if the main CPU is rea= lly =2D * slow, it's possible we see the current "ready" response. Since t= hat =2D * can't be distinguished from the previous response in polled mode, =2D * this is a potential issue. We really should have interrupts enab= led =2D * during boot so there is no ambiguity in polled mode. =2D * =2D * If this occurs, we add an additional delay before actually enteri= ng =2D * the status checking loop, hopefully to allow the EC to go to work =2D * and produce a non-stale status. =2D */ =2D if (need_poll) { =2D static int once; =2D =2D if (EcCheckStatus(sc, "pre-check", Event) =3D=3D AE_OK) { =2D if (!once) { =2D device_printf(sc->ec_dev, =2D "warning: EC done before starting event wait\n"); =2D once =3D 1; =2D } =2D AcpiOsStall(10); =2D } =2D } =20 /* Wait for event by polling or GPE (interrupt). */ if (need_poll) { count =3D (ec_timeout * 1000) / EC_POLL_DELAY; if (count =3D=3D 0) count =3D 1; + + /* The EC is slow, give it some time to catch up to us */ + AcpiOsStall(100); for (i =3D 0; i < count; i++) { Status =3D EcCheckStatus(sc, "poll", Event); if (Status =3D=3D AE_OK) break; AcpiOsStall(EC_POLL_DELAY); } + + if (Status !=3D AE_OK) + device_printf(sc->ec_dev, "wait timed out [polling mode]\n"); } else { =2D slp_ival =3D hz / 1000; =2D if (slp_ival !=3D 0) { =2D count =3D ec_timeout; =2D } else { =2D /* hz has less than 1 ms resolution so scale timeout. */ =2D slp_ival =3D 1; =2D count =3D ec_timeout / (1000 / hz); =2D } + /* How many ticks should we sleep for (max) */ + req_ticks =3D hz < 1000 ? (ec_timeout * hz) / 1000 + : (ec_timeout * 1000) / hz; + /* Make sure we sleep for at least one tick, from now */ + cur_ticks =3D (volatile int)ticks; + req_ticks =3D cur_ticks + (req_ticks ? req_ticks : 1) + 1; =20 /* * Wait for the GPE to signal the status changed, checking the @@ -867,38 +856,42 @@ * GPE for an event we're not interested in here (i.e., SCI for * EC query). */ =2D for (i =3D 0; i < count; i++) { =2D if (gen_count !=3D sc->ec_gencount) { =2D /* =2D * Record new generation count. It's possible the GPE was =2D * just to notify us that a query is needed and we need to =2D * wait for a second GPE to signal the completion of the =2D * event we are actually waiting for. =2D */ =2D gen_count =3D sc->ec_gencount; =2D Status =3D EcCheckStatus(sc, "sleep", Event); =2D if (Status =3D=3D AE_OK) =2D break; =2D } =2D tsleep(&sc->ec_gencount, PZERO, "ecgpe", slp_ival); + while ((int)(req_ticks - cur_ticks) > 0) { + /* If we have not received a signal then wait for one */ + if (gen_count =3D=3D sc->ec_gencount) + tsleep(&sc->ec_gencount, PZERO, "ecgpe", req_ticks - cur_ticks); + + /* + * Record new generation count. It's possible the GPE was + * just to notify us that a query is needed and we need to + * wait for a second GPE to signal the completion of the + * event we are actually waiting for. + */ + gen_count =3D sc->ec_gencount; + Status =3D EcCheckStatus(sc, "sleep", Event); + if (Status =3D=3D AE_OK) + break; + + /* Update current tick (so we always have a consistant value */ + cur_ticks =3D (volatile int)ticks; } =20 /* =2D * We finished waiting for the GPE and it never arrived. Try to =2D * read the register once and trust whatever value we got. This is =2D * the best we can do at this point. Then, force polled mode on =2D * since this system doesn't appear to generate GPEs. + * We finished waiting for the GPE and it never arrived. The register + * has been read on a timeout so no need to re-read it. Force polled + * mode on since this system doesn't appear to generate GPEs. */ if (Status !=3D AE_OK) { =2D Status =3D EcCheckStatus(sc, "sleep_end", Event); =2D device_printf(sc->ec_dev, =2D "wait timed out (%sresponse), forcing polled mode\n", =2D Status =3D=3D AE_OK ? "" : "no "); =2D ec_polled_mode =3D TRUE; + device_printf(sc->ec_dev, "wait timed out [GPE mode]%s\n", + ec_gpe_mode ? "" : ", forcing polled mode"); + ec_polled_mode =3D TRUE && !ec_gpe_mode; } } if (Status !=3D AE_OK) CTR0(KTR_ACPI, "error: ec wait timed out"); + else if (ec_delay); + /* Give the EC a chance to recover from all its hard work!!! */ + AcpiOsStall(ec_delay); return (Status); } =20 --Boundary-01=_k3tXK33FiTl0Q0d-- --nextPart2225410.334euvKaTl Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (FreeBSD) iEYEABECAAYFAkpe3egACgkQUaaFgP9pFrKQkACdGnaCZLwWpuzbfJ3UNT+4Qe7k wx4AnAvi2P+7Oa6NgRUfwIOM7gC7S0pd =oieh -----END PGP SIGNATURE----- --nextPart2225410.334euvKaTl--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907160959.37024.naylor.b.david>