05.04.2023 03:45, joshua stein пишет:
> acpithinkpad sets up a hard-coded number of temperature sensors and 
> doesn't check the result of aml_evalinteger when polling, so for all 
> invalid sensors it ends up reporting the value of the previous 
> successful sensor check resulting in this (for a machine with only a 
> TMP0 sensor):
> 
> hw.sensors.acpithinkpad0.temp0=47.00 degC
> hw.sensors.acpithinkpad0.temp1=47.00 degC
> hw.sensors.acpithinkpad0.temp2=47.00 degC
> hw.sensors.acpithinkpad0.temp3=47.00 degC
> hw.sensors.acpithinkpad0.temp4=47.00 degC
> hw.sensors.acpithinkpad0.temp5=47.00 degC
> hw.sensors.acpithinkpad0.temp6=47.00 degC
> hw.sensors.acpithinkpad0.temp7=47.00 degC
> hw.sensors.acpithinkpad0.fan0=3605 RPM
> hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN
> 
> This diff checks whether the TMP[0-8] node actually exists during 
> attach and if not, it doesn't create the sensor.  It also checks the 
> return value during polling and sets the sensor to invalid if it 
> failed for some reason.

This makes sense, however...

> 
> hw.sensors.acpithinkpad0.temp0=55.00 degC
> hw.sensors.acpithinkpad0.fan0=5045 RPM
> hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN
> 
> 
> Index: sys/dev/acpi/acpithinkpad.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v
> retrieving revision 1.70
> diff -u -p -u -p -r1.70 acpithinkpad.c
> --- sys/dev/acpi/acpithinkpad.c       6 Apr 2022 18:59:27 -0000       1.70
> +++ sys/dev/acpi/acpithinkpad.c       5 Apr 2023 03:43:59 -0000
> @@ -112,11 +112,10 @@
>  #define      THINKPAD_TABLET_SCREEN_CHANGED  0x60c0
>  #define      THINKPAD_SWITCH_WIRELESS        0x7000
>  
> -#define THINKPAD_NSENSORS 10
> -#define THINKPAD_NTEMPSENSORS 8
> -
> -#define THINKPAD_SENSOR_FANRPM               THINKPAD_NTEMPSENSORS
> -#define THINKPAD_SENSOR_PORTREPL     THINKPAD_NTEMPSENSORS + 1
> +#define THINKPAD_SENSOR_FANRPM               0
> +#define THINKPAD_SENSOR_PORTREPL     1
> +#define THINKPAD_SENSOR_TMP0         2
> +#define THINKPAD_NSENSORS            10
>  
>  #define THINKPAD_ECOFFSET_VOLUME     0x30
>  #define THINKPAD_ECOFFSET_VOLUME_MUTE_MASK 0x40
> @@ -140,6 +139,7 @@ struct acpithinkpad_softc {
>  
>       struct ksensor           sc_sens[THINKPAD_NSENSORS];
>       struct ksensordev        sc_sensdev;
> +     int                      sc_ntempsens;
>  
>       uint64_t                 sc_hkey_version;
>  
> @@ -178,6 +178,7 @@ int       thinkpad_get_brightness(struct acpit
>  int  thinkpad_set_brightness(void *, int);
>  int  thinkpad_get_param(struct wsdisplay_param *);
>  int  thinkpad_set_param(struct wsdisplay_param *);
> +int  thinkpad_get_temp(struct acpithinkpad_softc *, int, int64_t *);
>  
>  void    thinkpad_sensor_attach(struct acpithinkpad_softc *sc);
>  void    thinkpad_sensor_refresh(void *);
> @@ -228,6 +229,7 @@ thinkpad_match(struct device *parent, vo
>  void
>  thinkpad_sensor_attach(struct acpithinkpad_softc *sc)
>  {
> +     int64_t tmp;
>       int i;
>  
>       if (sc->sc_acpi->sc_ec == NULL)
> @@ -237,10 +239,16 @@ thinkpad_sensor_attach(struct acpithinkp
>       /* Add temperature probes */
>       strlcpy(sc->sc_sensdev.xname, DEVNAME(sc),
>           sizeof(sc->sc_sensdev.xname));
> -     for (i=0; i<THINKPAD_NTEMPSENSORS; i++) {
> -             sc->sc_sens[i].type = SENSOR_TEMP;
> -             sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]);
> -     }
> +     sc->sc_ntempsens = 0;
> +     for (i = 0; i < THINKPAD_NSENSORS - THINKPAD_SENSOR_TMP0; i++) {
> +             if (thinkpad_get_temp(sc, i, &tmp) != 0)
> +                     break;

doesn't this mean, that legit sensors which happen to fail this read
upon attach won't ever be visible at runtime?

I have no idea how reliable those sensors are, but given that the code
handles spurious failure, this seems not too far fetched.

> +
> +             sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].type = SENSOR_TEMP;
> +             sensor_attach(&sc->sc_sensdev,
> +                 &sc->sc_sens[THINKPAD_SENSOR_TMP0 + i]);
> +             sc->sc_ntempsens++;
> +     }
>  
>       /* Add fan probe */
>       sc->sc_sens[THINKPAD_SENSOR_FANRPM].type = SENSOR_FANRPM;
> @@ -262,17 +270,19 @@ thinkpad_sensor_refresh(void *arg)
>       struct acpithinkpad_softc *sc = arg;
>       uint8_t lo, hi, i;
>       int64_t tmp;
> -     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;
> -     }
> +     for (i = 0; i < sc->sc_ntempsens; i++) {
> +             if (thinkpad_get_temp(sc, i, &tmp) != 0) {
> +                     sc->sc_sens[i].flags = SENSOR_FINVALID;
> +                     continue;
> +             }
> +
> +             sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].value =
> +                 (tmp * 1000000) + 273150000;
> +             sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].flags =
> +                 (tmp > 127 || tmp < -127) ? SENSOR_FINVALID : 0;
> +     }
>  
>       /* Read fan RPM */
>       acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo);
> @@ -321,10 +331,8 @@ thinkpad_attach(struct device *parent, s
>               wskbd_set_backlight = thinkpad_set_kbd_backlight;
>       }
>  
> -     /* On version 2 and newer, let *drm or acpivout control brightness */
> -     if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION1 &&
> -         (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG",
> -         0, NULL, &sc->sc_brightness) == 0)) {
> +     if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG",
> +         0, NULL, &sc->sc_brightness) == 0) {
>               ws_get_param = thinkpad_get_param;
>               ws_set_param = thinkpad_set_param;
>       }

Is this an unrelated diff that snuck in?

> @@ -785,6 +793,20 @@ thinkpad_set_param(struct wsdisplay_para
>       default:
>               return -1;
>       }
> +}
> +
> +int
> +thinkpad_get_temp(struct acpithinkpad_softc *sc, int idx, int64_t *temp)
> +{
> +     char sname[5];
> +
> +     snprintf(sname, sizeof(sname), "TMP%d", idx);
> +
> +     if (aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode, sname, 0, 0,
> +         temp) != 0)
> +             return (1);

Looks liks aml_evalnode(9) only returns 0/success or
ACPI_E_BADVALUE/failure anyway, so there's no way to distinguish between
nonexistent sensors and existent but failing sensors, right?

> +
> +     return (0);
>  }
>  
>  #if NAUDIO > 0 && NWSKBD > 0
> 

Reply via email to