Hi, I have encounter problem with acpitz: basically with acpitz enable, a fan keep running at max speed (with lot of noise).
I have traced the problem (see http://marc.info/?l=openbsd-bugs&m=140517557620686&w=2 for reference). As I haven't received any indications, I go to the ACPI spec in order to understand what happens. Currently, I'm not sure to understand all the terms, so please correct my if I am wrong: that would help me ! The host is an HP compaq nc6400 (see dmesg from previous reference if need). >From what I understand, the host use notify 0x81 when temperature pass an active point. The spec say it is ok: "The following are the primary uses for this type of thermal notification: - ... - ... - After the crossing of an active or passive trip point is signaled to implement hysteresis." The current code in acpitz.c for 0x81 notify is to reread TRIP points (passive: _PSV and actives: _ACx), and for active points, to reinitiate sc_ac_stat (which seems to keep the current state of fan: -1=uninitialized / 0=OFF / 1=ON). sc_ac_stat is taken from _STA: "Returns the current ON or OFF status for the power resource." (0=OFF / 1=ON) The problem is the code set sc_ac_stat to -1, whereas fan could be ON. >From dev/acpi/acpitz.c: > /* active cooling */ > for (i = 0; i < ACPITZ_MAX_AC; i++) { > if (sc->sc_ac[i] != -1 && sc->sc_ac[i] <= sc->sc_tmp) { > /* turn on fan i */ > if (sc->sc_ac_stat[i] <= 0) > acpitz_setfan(sc, i, "_ON_"); > } else if (sc->sc_ac[i] != -1) { > /* turn off fan i */ > if (sc->sc_ac_stat[i] > 0) > acpitz_setfan(sc, i, "_OFF"); > } > } The active cooling code could set the fan ON if sc_ac_stat is -1, but couldn't set the fan OFF... So when a notify 0x81 occurs and the fan is ON, sc_ac_stat is set to -1, and as the temperature will keep low, the active cooling will not do anything... keeping the fan running. So I have change the round-trip reinitialization to not bindly set -1 to sc_ac_stat, but reread the corresponding _STA instead of. The following patch acheive this by: - change acpitz_setfan function to allow a NULL method (instead of "_ON_" or "_OFF" values only). The purpose is to reuse the codepath that read _STA, but without set the fan ON or OFF. - call acpitz_setfan with NULL during acpitz_init, when reading trip points. It always set sc_ac_stat=-1, but if no error in acpitz_setfan occurs, the call will set sc_ac_stat= _STA. Another possibility (not tested) should be to change active cooling code to permit call acpitz_setfan(OFF) when sc_ac_stat == -1. Thanks to comment. -- Sébastien Marie Index: src-sys-current/dev/acpi/acpitz.c =================================================================== --- src-sys-current.orig/dev/acpi/acpitz.c +++ src-sys-current/dev/acpi/acpitz.c @@ -141,6 +141,7 @@ acpitz_init(struct acpitz_softc *sc, int snprintf(name, sizeof(name), "_AC%d", i); sc->sc_ac[i] = acpitz_getreading(sc, name); sc->sc_ac_stat[i] = -1; + acpitz_setfan(sc, i, NULL); } } @@ -317,8 +318,8 @@ acpitz_setfan(struct acpitz_softc *sc, i DEVNAME(sc), name, x, y); continue; } - if (aml_evalname(sc->sc_acpi, ref->node, method, 0, - NULL, NULL)) + if (method != NULL && aml_evalname(sc->sc_acpi, ref->node, + method, 0, NULL, NULL)) printf("%s: %s[%d.%d] %s fails\n", DEVNAME(sc), name, x, y, method);
