diff --git a/Cargo.toml b/Cargo.toml index c0ce01c6fc..f2ca28b04a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -145,6 +145,16 @@ precedence = "deny" # for any platform with Modern Standby firmware (Dell, HP, # Lenovo, LG Gram, etc.). redox_syscall = { path = "../syscall" } +# Red Bear OS Phase J: libredox 0.1.17 has its own vendored +# redox_syscall dep. Without the libredox override here, +# libredox::error::Error is the upstream syscall::error::Error +# (a different compile-time type than the local fork's +# syscall::Error) and the conversion `?` operator in +# scheme-utils / daemon fails with E0277. Override libredox +# to use the local fork at ../libredox/ (which itself uses +# the local syscall fork). Now libredox::error::Error and +# syscall::Error are the same type. +libredox = { path = "../libredox" } [patch."https://gitlab.redox-os.org/redox-os/relibc.git"] #redox-ioctl = { path = "../../relibc/source/redox-ioctl" } diff --git a/drivers/acpid/src/scheme.rs b/drivers/acpid/src/scheme.rs index 041e7721f6..da9180948a 100644 --- a/drivers/acpid/src/scheme.rs +++ b/drivers/acpid/src/scheme.rs @@ -169,6 +169,32 @@ impl<'acpi, 'sock> AcpiScheme<'acpi, 'sock> { let result = handle.call_ro(&mut payload, CallFlags::empty(), &[verb])?; Ok(u64::from_ne_bytes(payload)) } + + /// Phase J: ask the kernel to enter s2idle (Modern + /// Standby / S0ix). This is the typed-AcpiVerb equivalent + /// of writing "s2idle" to /scheme/sys/kstop — the kstop + /// string-arg path was Phase I.5's fallback while we + /// couldn't extend the syscall crate due to the libredox + /// cross-version issue. Phase J: with the local libredox + /// fork (which uses the local syscall fork with + /// EnterS2Idle/ExitS2Idle), this typed path is the + /// preferred API. The kstop string-arg path remains for + /// backward compatibility with older acpid builds. + /// + /// Hardware-agnostic: works for any platform with Modern + /// Standby firmware (Dell, HP, Lenovo, LG Gram, etc.). + /// Mirrors Linux 7.1 `acpi_s2idle_begin` in + /// `kernel/power/suspend.c:91`. + pub fn kstop_enter_s2idle(&self) -> syscall::Result<()> { + let handle = self.kstop_fd.ok_or(syscall::error::Error::new(syscall::error::EBADF))?; + let verb = AcpiVerb::EnterS2Idle as u64; + // AcpiVerb::EnterS2Idle doesn't need a write payload; + // the verb code itself is the signal. The kernel + // sets S2IDLE_REQUESTED + signals the kstop handle's + // EVENT_READ. + handle.call_wo(&[], CallFlags::empty(), &[verb])?; + Ok(()) + } } fn parse_hex_digit(hex: u8) -> Option {