My original diff would be an improvement, but I think it is not sufficient,
because I have found some more problems with the refresh code.
The return value of aml_evalinteger is not checked and it sporadically _does_
return ACPI_E_BADVALUE. When aml_evalinteger returns non-zero, tmp is not
touched and is either uninitialized or retains the value from the previous
loop iteration. So sysctl shows 8 temperature sensors on my machine, all with
the same temperature, while only in the first loop iteration the aml_evalinteger
returned successfully.
Additionally during the wake up time after suspend the tmp value is 128 if
aml_evalinteger succeeds and the fan speed is reported as 65535.

The following diff addresses these issues by:
 * checking the return value of aml_evalinteger and setting the SENSOR_FINVALID
   flag when it is non-zero
 * setting the SENSOR_FUNKNOWN flag when tmp is 128
 * printf an error message when the temperature is invalid even though
   aml_evalinteger returned 0 (but resetting the flags to 0 on the next run so
   the sensor doesn't vanish forever)
 * setting the SENSOR_FUNKNOWN flag when fan speed is 65535

After applying the diff the number of sensors displayed on my Thinkpad T520 is
reduced to one. Both the temperature sensors and the fan speed sensors
show "unknown" instead of disappearing during the wake up time.

comments?

regards
natano


Index: dev/acpi/acpithinkpad.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v
retrieving revision 1.30
diff -u -p -r1.30 acpithinkpad.c
--- dev/acpi/acpithinkpad.c     2 Apr 2013 00:46:47 -0000       1.30
+++ dev/acpi/acpithinkpad.c     29 Jun 2013 09:07:17 -0000
@@ -178,23 +178,33 @@ thinkpad_sensor_refresh(void *arg)
 {
        struct acpithinkpad_softc *sc = arg;
        u_int8_t lo, hi, i;
-       int64_t tmp;
+       int64_t tmp, speed;
        char sname[5];
 
        /* Refresh sensor readings */
        for (i=0; i<THINKPAD_NTEMPSENSORS; i++) {
                snprintf(sname, sizeof(sname), "TMP%d", i);
-               aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode,
-                   sname, 0, 0, &tmp);
-               sc->sc_sens[i].value = (tmp * 1000000) + 273150000;
-               if (tmp > 127 || tmp < -127)
-                       sc->sc_sens[i].flags = SENSOR_FINVALID;
+               if (!aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode,
+                   sname, 0, 0, &tmp)) {
+                       sc->sc_sens[i].value = (tmp * 1000000) + 273150000;
+                       sc->sc_sens[i].flags = 0;
+                       if (tmp == 128) {
+                               sc->sc_sens[i].flags |= SENSOR_FUNKNOWN;
+                       } else if (tmp > 127 || tmp < -127) {
+                               printf("%s: invalid temperature: %lld\n",
+                                   DEVNAME(sc), tmp);
+                               sc->sc_sens[i].flags |= SENSOR_FINVALID;
+                       }
+               } else
+                       sc->sc_sens[i].flags |= SENSOR_FINVALID;
        }
 
        /* Read fan RPM */
        acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo);
        acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANHI, 1, &hi);
-       sc->sc_sens[i].value = ((hi << 8L) + lo);
+       speed = ((hi << 8L) + lo);
+       sc->sc_sens[i].value = speed;
+       sc->sc_sens[i].flags = (speed == 0xffff) ? SENSOR_FUNKNOWN : 0;
 }
 
 void


On Sat, Jun 29, 2013 at 12:51:29PM +0400, Vadim Zhukov wrote:
> I got the point. So it's up to sysadmin to trust or not the sensor data.
> Then original patch should be fine, except small nit - I think,
> it's better to reset only SENSOR_FINVALID flag instead of all.
> 
> CC'ing ACPI guys for okays.
> 
> --
>   WBR,
>     Vadim Zhukov
> 
> 
> Index: acpithinkpad.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 acpithinkpad.c
> --- acpithinkpad.c    2 Apr 2013 00:46:47 -0000       1.30
> +++ acpithinkpad.c    29 Jun 2013 08:41:46 -0000
> @@ -189,6 +189,8 @@ thinkpad_sensor_refresh(void *arg)
>               sc->sc_sens[i].value = (tmp * 1000000) + 273150000;
>               if (tmp > 127 || tmp < -127)
>                       sc->sc_sens[i].flags = SENSOR_FINVALID;
> +             else
> +                     sc->sc_sens[i].flags &= ~SENSOR_FINVALID;
>       }
>  
>       /* Read fan RPM */

Reply via email to