diff --git a/etc/devd.conf b/etc/devd.conf index cc7a20871a26..f9453ecde2f3 100644 --- a/etc/devd.conf +++ b/etc/devd.conf @@ -74,7 +74,17 @@ nomatch 0 { notify 10 { match "system" "ACPI"; match "subsystem" "ACAD"; - action "/etc/rc.d/power_profile $notify"; + action "/etc/rc.d/power_profile $notify"; +}; + +# Notify all users before beginning emergency shutdown when we get +# a _CRT or _HOT thermal event and we're going to power down the system +# very soon. +notify 10 { + match "system" "ACPI"; + match "subsystem" "Thermal"; + match "notify" "0xcc"; + action "logger -p kern.emerg 'WARNING: system temperature too high, shutting down soon!'"; }; /* EXAMPLES TO END OF FILE diff --git a/share/man/man4/acpi_thermal.4 b/share/man/man4/acpi_thermal.4 index d22bf690e3b1..28467fa1eff8 100644 --- a/share/man/man4/acpi_thermal.4 +++ b/share/man/man4/acpi_thermal.4 @@ -115,6 +115,9 @@ Current temperature has changed. One or more trip points (_ACx, _PSV) have changed. .It Li 0x82 One or more device lists (_ALx, _PSL, _TZD) have changed. +.It Li 0xcc +Non-standard notify that the system will shutdown if the temperature +stays above _CRT or _HOT for one more poll cycle. .El .El .Sh SEE ALSO diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c index 32fb55157c06..03d50cedd117 100644 --- a/sys/dev/acpica/acpi_thermal.c +++ b/sys/dev/acpica/acpi_thermal.c @@ -49,9 +49,10 @@ ACPI_MODULE_NAME("THERMAL") #define TZ_ZEROC 2732 #define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), (((x) - TZ_ZEROC) % 10) -#define TZ_NOTIFY_TEMPERATURE 0x80 -#define TZ_NOTIFY_LEVELS 0x81 -#define TZ_NOTIFY_DEVICES 0x82 +#define TZ_NOTIFY_TEMPERATURE 0x80 /* Temperature changed. */ +#define TZ_NOTIFY_LEVELS 0x81 /* Cooling levels changed. */ +#define TZ_NOTIFY_DEVICES 0x82 /* Device lists changed. */ +#define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT reached. */ /* Check for temperature changes every 10 seconds by default */ #define TZ_POLLRATE 10 @@ -59,6 +60,9 @@ ACPI_MODULE_NAME("THERMAL") /* Make sure the reported temperature is valid for this number of polls. */ #define TZ_VALIDCHECKS 3 +/* Notify the user we will be shutting down in one more poll cycle. */ +#define TZ_NOTIFYCOUNT (TZ_VALIDCHECKS - 1) + /* ACPI spec defines this */ #define TZ_NUMLEVELS 10 struct acpi_tz_zone { @@ -481,14 +485,18 @@ acpi_tz_monitor(void *Context) * for one poll cycle. It is suspected this is due to the embedded * controller timing out. A typical value is 138C for one cycle on * a system that is otherwise 65C. + * + * If we're almost at that threshold, notify the user through devd(8). */ if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) { - if (++sc->tz_validchecks == TZ_VALIDCHECKS) { + sc->tz_validchecks++; + if (sc->tz_validchecks == TZ_VALIDCHECKS) { device_printf(sc->tz_dev, "WARNING - current temperature (%d.%dC) exceeds safe limits\n", TZ_KELVTOC(sc->tz_temperature)); shutdown_nice(RB_POWEROFF); - } + } else if (sc->tz_validchecks == TZ_NOTIFYCOUNT) + acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL); } else { sc->tz_validchecks = 0; }