diff --git a/drivers/acpid/src/scheme.rs b/drivers/acpid/src/scheme.rs index e0b2b35f54..5bdcda3253 100644 --- a/drivers/acpid/src/scheme.rs +++ b/drivers/acpid/src/scheme.rs @@ -66,6 +66,7 @@ enum HandleKind<'a> { /// thermal zones (headless QEMU, desktops) the directory /// listing is empty. Thermal, + ThermalZone { zone: String, kind: ThermalFileKind }, /// `/scheme/acpi/power` -- entries are PowerResource objects in /// the AML namespace. On laptops these are AC adapters and /// battery controllers. On desktops and QEMU the listing is @@ -120,6 +121,13 @@ enum PowerFileKind { Online, } +#[derive(Clone, Copy, Debug)] +enum ThermalFileKind { + Temperature, + Passive, + Critical, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ProcFileKind { Pss, @@ -139,6 +147,7 @@ impl HandleKind<'_> { Self::SchemeRoot => false, Self::RegisterPci => false, Self::Thermal | Self::Power | Self::Processor | Self::DmiDir | Self::PowerBatteries => true, + Self::ThermalZone { .. } => false, Self::PowerBattery { .. } | Self::PowerAdapter { .. } => false, Self::Dmi => true, Self::DmiField(_) => false, @@ -172,6 +181,7 @@ impl HandleKind<'_> { Self::Button { .. } => 2, Self::Notifications | Self::Lid | Self::ButtonDir | Self::Fan => 0, Self::FanState(_) | Self::FanSpeed(_) => 4, + Self::ThermalZone { .. } => 16, // Directories Self::TopLevel | Self::Symbols(_) | Self::Tables => 0, Self::Thermal | Self::Power | Self::Processor | Self::DmiDir => 0, @@ -407,6 +417,23 @@ impl SchemeSync for AcpiScheme<'_, '_> { ["register_pci"] => HandleKind::RegisterPci, ["tables"] => HandleKind::Tables, ["thermal"] => HandleKind::Thermal, + ["thermal", zone_name, file] => { + let zones = self.ctx.thermal_zones(); + let zone_path = format!("\\_TZ.{}", zone_name); + if !zones.contains(&zone_path) { + return Err(Error::new(ENOENT)); + } + let kind = match *file { + "temperature" => ThermalFileKind::Temperature, + "passive" => ThermalFileKind::Passive, + "critical" => ThermalFileKind::Critical, + _ => return Err(Error::new(ENOENT)), + }; + HandleKind::ThermalZone { + zone: zone_path, + kind, + } + } ["power"] => HandleKind::Power, ["dmi"] => HandleKind::Dmi, ["processor"] => HandleKind::Processor, @@ -651,6 +678,20 @@ impl SchemeSync for AcpiScheme<'_, '_> { dmi_buf = if lines.is_empty() { lines } else { format!("{lines}\n") }; dmi_buf.as_bytes() } + HandleKind::ThermalZone { zone, kind } => { + let method = match kind { + ThermalFileKind::Temperature => "_TMP", + ThermalFileKind::Passive => "_PSV", + ThermalFileKind::Critical => "_CRT", + }; + let values = self + .ctx + .evaluate_acpi_method(zone, method, &[]) + .map_err(|_| Error::new(EIO))?; + let raw = values.first().copied().unwrap_or(0); + dmi_buf = format!("{}\n", raw); + dmi_buf.as_bytes() + } HandleKind::Processor | HandleKind::DmiDir | HandleKind::Thermal | HandleKind::Power | HandleKind::PowerBatteries | HandleKind::Symbols(_) | HandleKind::RegisterPci | HandleKind::TopLevel | HandleKind::SchemeRoot | HandleKind::Lid | HandleKind::ButtonDir | HandleKind::Fan => { return Err(Error::new(EISDIR)); }