mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
VFIO mode enabled
This commit is contained in:
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Refactor keyboard LED handling
|
- Refactor keyboard LED handling
|
||||||
- Added --list for profiles (Thanks @aqez)
|
- Added --list for profiles (Thanks @aqez)
|
||||||
- Added --remove for profiles (Thanks @aqez)
|
- Added --remove for profiles (Thanks @aqez)
|
||||||
|
- Added a graphics mode: vfio. This attaches Nvidia devices to vfio module.
|
||||||
### Broken
|
### Broken
|
||||||
- Per-key LED modes, which need thinking about how to go ahead with for future
|
- Per-key LED modes, which need thinking about how to go ahead with for future
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
if let Some(notif) = last_gfx_notif.take() {
|
if let Some(notif) = last_gfx_notif.take() {
|
||||||
notif.close();
|
notif.close();
|
||||||
}
|
}
|
||||||
let x = do_notif(&format!("Graphics mode changed to {}", vendor))?;
|
let x = do_notif(&format!(
|
||||||
|
"Graphics mode changed to {}",
|
||||||
|
<&str>::from(vendor)
|
||||||
|
))?;
|
||||||
last_gfx_notif = Some(x);
|
last_gfx_notif = Some(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use gumdrop::Options;
|
||||||
use rog_types::{
|
use rog_types::{
|
||||||
aura_modes::{Colour, Direction, Speed, AuraEffect, AuraModeNum, AuraZone},
|
aura_modes::{AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed},
|
||||||
error::AuraError,
|
error::AuraError,
|
||||||
};
|
};
|
||||||
use gumdrop::Options;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -165,7 +165,6 @@ impl Default for SetAuraBuiltin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl From<&SingleColour> for AuraEffect {
|
impl From<&SingleColour> for AuraEffect {
|
||||||
fn from(aura: &SingleColour) -> Self {
|
fn from(aura: &SingleColour) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -294,15 +293,15 @@ impl From<&SetAuraBuiltin> for Vec<AuraEffect> {
|
|||||||
zones[1].mode = AuraModeNum::Static;
|
zones[1].mode = AuraModeNum::Static;
|
||||||
zones[1].zone = AuraZone::Two;
|
zones[1].zone = AuraZone::Two;
|
||||||
zones[1].colour1 = data.colour2;
|
zones[1].colour1 = data.colour2;
|
||||||
|
|
||||||
zones[2].mode = AuraModeNum::Static;
|
zones[2].mode = AuraModeNum::Static;
|
||||||
zones[2].zone = AuraZone::Three;
|
zones[2].zone = AuraZone::Three;
|
||||||
zones[2].colour1 = data.colour3;
|
zones[2].colour1 = data.colour3;
|
||||||
|
|
||||||
zones[3].mode = AuraModeNum::Static;
|
zones[3].mode = AuraModeNum::Static;
|
||||||
zones[3].zone = AuraZone::Four;
|
zones[3].zone = AuraZone::Four;
|
||||||
zones[3].colour1 = data.colour4;
|
zones[3].colour1 = data.colour4;
|
||||||
},
|
}
|
||||||
SetAuraBuiltin::MultiBreathe(data) => {
|
SetAuraBuiltin::MultiBreathe(data) => {
|
||||||
zones[0].mode = AuraModeNum::Breathe;
|
zones[0].mode = AuraModeNum::Breathe;
|
||||||
zones[0].zone = AuraZone::One;
|
zones[0].zone = AuraZone::One;
|
||||||
@@ -313,19 +312,19 @@ impl From<&SetAuraBuiltin> for Vec<AuraEffect> {
|
|||||||
zones[1].zone = AuraZone::Two;
|
zones[1].zone = AuraZone::Two;
|
||||||
zones[1].colour1 = data.colour2;
|
zones[1].colour1 = data.colour2;
|
||||||
zones[1].speed = data.speed;
|
zones[1].speed = data.speed;
|
||||||
|
|
||||||
zones[2].mode = AuraModeNum::Breathe;
|
zones[2].mode = AuraModeNum::Breathe;
|
||||||
zones[2].zone = AuraZone::Three;
|
zones[2].zone = AuraZone::Three;
|
||||||
zones[2].colour1 = data.colour3;
|
zones[2].colour1 = data.colour3;
|
||||||
zones[2].speed = data.speed;
|
zones[2].speed = data.speed;
|
||||||
|
|
||||||
zones[3].mode = AuraModeNum::Breathe;
|
zones[3].mode = AuraModeNum::Breathe;
|
||||||
zones[3].zone = AuraZone::Four;
|
zones[3].zone = AuraZone::Four;
|
||||||
zones[3].colour1 = data.colour4;
|
zones[3].colour1 = data.colour4;
|
||||||
zones[3].speed = data.speed;
|
zones[3].speed = data.speed;
|
||||||
}
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
zones
|
zones
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
mod aura_cli;
|
mod aura_cli;
|
||||||
|
|
||||||
|
use crate::aura_cli::{LedBrightness, SetAuraBuiltin};
|
||||||
use daemon::{
|
use daemon::{
|
||||||
ctrl_fan_cpu::FanCpuSupportedFunctions, ctrl_leds::LedSupportedFunctions,
|
ctrl_fan_cpu::FanCpuSupportedFunctions, ctrl_leds::LedSupportedFunctions,
|
||||||
ctrl_rog_bios::RogBiosSupportedFunctions, ctrl_supported::SupportedFunctions,
|
ctrl_rog_bios::RogBiosSupportedFunctions, ctrl_supported::SupportedFunctions,
|
||||||
@@ -16,7 +17,6 @@ use rog_types::{
|
|||||||
use std::env::args;
|
use std::env::args;
|
||||||
use yansi_term::Colour::Green;
|
use yansi_term::Colour::Green;
|
||||||
use yansi_term::Colour::Red;
|
use yansi_term::Colour::Red;
|
||||||
use crate::aura_cli::{LedBrightness, SetAuraBuiltin};
|
|
||||||
|
|
||||||
#[derive(Default, Options)]
|
#[derive(Default, Options)]
|
||||||
struct CLIStart {
|
struct CLIStart {
|
||||||
@@ -286,19 +286,24 @@ fn do_gfx(
|
|||||||
std::process::exit(-1);
|
std::process::exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!("If anything fails check `journalctl -b -u asusd`\n");
|
||||||
"Your display-manager will restart in requested mode when all users are logged out"
|
|
||||||
);
|
|
||||||
println!("If anything fails check `journalctl -b -u asusd`");
|
|
||||||
|
|
||||||
dbus.proxies().gfx().gfx_write_mode(mode.into())?;
|
dbus.proxies().gfx().gfx_write_mode(&mode).map_err(|err|{
|
||||||
|
println!("Graphics mode change error. You may be in an invalid state.");
|
||||||
|
println!("Check mode with `asusctl graphics -g` and switch to opposite\nmode to correct it, e.g: if integrated, switch to hybrid, or if nvidia, switch to integrated.\n");
|
||||||
|
err
|
||||||
|
})?;
|
||||||
let res = dbus.gfx_wait_changed()?;
|
let res = dbus.gfx_wait_changed()?;
|
||||||
println!("{}", res);
|
println!(
|
||||||
|
"Graphics mode changed to {}. User action required is: {}",
|
||||||
|
<&str>::from(mode),
|
||||||
|
<&str>::from(&res)
|
||||||
|
);
|
||||||
std::process::exit(0)
|
std::process::exit(0)
|
||||||
}
|
}
|
||||||
if command.get {
|
if command.get {
|
||||||
let res = dbus.proxies().gfx().gfx_get_mode()?;
|
let res = dbus.proxies().gfx().gfx_get_mode()?;
|
||||||
println!("Current graphics mode: {}", res);
|
println!("Current graphics mode: {}", <&str>::from(res));
|
||||||
}
|
}
|
||||||
if command.pow {
|
if command.pow {
|
||||||
let res = dbus.proxies().gfx().gfx_get_pwr()?;
|
let res = dbus.proxies().gfx().gfx_get_pwr()?;
|
||||||
@@ -361,9 +366,7 @@ fn handle_led_mode(
|
|||||||
SetAuraBuiltin::MultiStatic(_) | SetAuraBuiltin::MultiBreathe(_) => {
|
SetAuraBuiltin::MultiStatic(_) | SetAuraBuiltin::MultiBreathe(_) => {
|
||||||
let zones = <Vec<AuraEffect>>::from(mode);
|
let zones = <Vec<AuraEffect>>::from(mode);
|
||||||
for eff in zones {
|
for eff in zones {
|
||||||
dbus.proxies()
|
dbus.proxies().led().set_led_mode(&eff)?
|
||||||
.led()
|
|
||||||
.set_led_mode(&eff)?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => dbus
|
_ => dbus
|
||||||
|
|||||||
@@ -160,7 +160,9 @@ impl DbusFanAndCpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.active_profile == *profile {
|
if cfg.active_profile == *profile {
|
||||||
return Err(Error::Failed("Cannot delete the active profile".to_string()));
|
return Err(Error::Failed(
|
||||||
|
"Cannot delete the active profile".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.power_profiles.remove(profile);
|
cfg.power_profiles.remove(profile);
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ use logind_zbus::{
|
|||||||
types::{SessionClass, SessionInfo, SessionType},
|
types::{SessionClass, SessionInfo, SessionType},
|
||||||
ManagerProxy, SessionProxy,
|
ManagerProxy, SessionProxy,
|
||||||
};
|
};
|
||||||
use rog_types::gfx_vendors::GfxVendors;
|
use rog_types::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
||||||
|
use std::sync::mpsc;
|
||||||
use std::{io::Write, ops::Add, path::Path, time::Instant};
|
use std::{io::Write, ops::Add, path::Path, time::Instant};
|
||||||
use std::{iter::FromIterator, thread::JoinHandle};
|
use std::{iter::FromIterator, thread::JoinHandle};
|
||||||
use std::{process::Command, thread::sleep, time::Duration};
|
use std::{process::Command, thread::sleep, time::Duration};
|
||||||
use std::{str::FromStr, sync::mpsc};
|
|
||||||
use std::{sync::Arc, sync::Mutex};
|
use std::{sync::Arc, sync::Mutex};
|
||||||
use sysfs_class::{PciDevice, SysClass};
|
use sysfs_class::{PciDevice, SysClass};
|
||||||
use system::{GraphicsDevice, PciBus};
|
use system::{GraphicsDevice, PciBus};
|
||||||
@@ -32,44 +32,44 @@ pub struct CtrlGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait Dbus {
|
trait Dbus {
|
||||||
fn vendor(&self) -> String;
|
fn vendor(&self) -> zbus::fdo::Result<GfxVendors>;
|
||||||
fn power(&self) -> String;
|
fn power(&self) -> String;
|
||||||
fn set_vendor(&mut self, vendor: String);
|
fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result<GfxRequiredUserAction>;
|
||||||
fn notify_gfx(&self, vendor: &str) -> zbus::Result<()>;
|
fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()>;
|
||||||
fn notify_action(&self, action: &str) -> zbus::Result<()>;
|
fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
impl Dbus for CtrlGraphics {
|
impl Dbus for CtrlGraphics {
|
||||||
fn vendor(&self) -> String {
|
fn vendor(&self) -> zbus::fdo::Result<GfxVendors> {
|
||||||
self.get_gfx_mode()
|
self.get_gfx_mode().map_err(|err| {
|
||||||
.map(|gfx| (<&str>::from(gfx)).into())
|
error!("GFX: {}", err);
|
||||||
.unwrap_or_else(|err| format!("Get vendor failed: {}", err))
|
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn power(&self) -> String {
|
fn power(&self) -> String {
|
||||||
Self::get_runtime_status().unwrap_or_else(|err| format!("Get power status failed: {}", err))
|
Self::get_runtime_status().unwrap_or_else(|err| format!("Get power status failed: {}", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vendor(&mut self, vendor: String) {
|
fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result<GfxRequiredUserAction> {
|
||||||
if let Ok(tmp) = GfxVendors::from_str(&vendor) {
|
info!("GFX: Switching gfx mode to {}", <&str>::from(vendor));
|
||||||
info!("GFX: Switching gfx mode to {}", vendor);
|
let msg = self.set_gfx_config(vendor).map_err(|err| {
|
||||||
let msg = self.set_gfx_config(tmp).unwrap_or_else(|err| {
|
error!("GFX: {}", err);
|
||||||
error!("GFX: {}", err);
|
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
||||||
format!("Failed: {}", err.to_string())
|
})?;
|
||||||
});
|
self.notify_gfx(&vendor)
|
||||||
self.notify_gfx(&vendor)
|
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
||||||
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
self.notify_action(&msg)
|
||||||
self.notify_action(&msg)
|
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
||||||
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
Ok(msg)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(signal)]
|
||||||
fn notify_gfx(&self, vendor: &str) -> zbus::Result<()> {}
|
fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()> {}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(signal)]
|
||||||
fn notify_action(&self, action: &str) -> zbus::Result<()> {}
|
fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZbusAdd for CtrlGraphics {
|
impl ZbusAdd for CtrlGraphics {
|
||||||
@@ -163,6 +163,7 @@ impl CtrlGraphics {
|
|||||||
self.nvidia.clone()
|
self.nvidia.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Save the selected `Vendor` mode to config
|
||||||
fn save_gfx_mode(vendor: GfxVendors, config: Arc<Mutex<Config>>) {
|
fn save_gfx_mode(vendor: GfxVendors, config: Arc<Mutex<Config>>) {
|
||||||
if let Ok(mut config) = config.lock() {
|
if let Ok(mut config) = config.lock() {
|
||||||
config.gfx_mode = vendor;
|
config.gfx_mode = vendor;
|
||||||
@@ -238,8 +239,40 @@ impl CtrlGraphics {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_modprobe_conf(content: &[u8]) -> Result<(), RogError> {
|
fn get_vfio_conf(devices: &[GraphicsDevice]) -> Vec<u8> {
|
||||||
|
let mut vifo = MODPROBE_VFIO.to_vec();
|
||||||
|
for (d_count, dev) in devices.iter().enumerate() {
|
||||||
|
for (f_count, func) in dev.functions().iter().enumerate() {
|
||||||
|
let vendor = func.vendor().unwrap();
|
||||||
|
let device = func.device().unwrap();
|
||||||
|
unsafe {
|
||||||
|
vifo.append(format!("{:x}", vendor).as_mut_vec());
|
||||||
|
}
|
||||||
|
vifo.append(&mut vec![b':']);
|
||||||
|
unsafe {
|
||||||
|
vifo.append(format!("{:x}", device).as_mut_vec());
|
||||||
|
}
|
||||||
|
if f_count < dev.functions().len() - 1 {
|
||||||
|
vifo.append(&mut vec![b',']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if d_count < dev.functions().len() - 1 {
|
||||||
|
vifo.append(&mut vec![b',']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut conf = MODPROBE_INTEGRATED.to_vec();
|
||||||
|
conf.append(&mut vifo);
|
||||||
|
conf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_modprobe_conf(vendor: GfxVendors, devices: &[GraphicsDevice]) -> Result<(), RogError> {
|
||||||
info!("GFX: Writing {}", MODPROBE_PATH);
|
info!("GFX: Writing {}", MODPROBE_PATH);
|
||||||
|
let content = match vendor {
|
||||||
|
GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Compute => MODPROBE_BASE.to_vec(),
|
||||||
|
GfxVendors::Vfio => Self::get_vfio_conf(devices),
|
||||||
|
// GfxVendors::Compute => {}
|
||||||
|
GfxVendors::Integrated => MODPROBE_INTEGRATED.to_vec(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut file = std::fs::OpenOptions::new()
|
let mut file = std::fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
@@ -248,7 +281,7 @@ impl CtrlGraphics {
|
|||||||
.open(MODPROBE_PATH)
|
.open(MODPROBE_PATH)
|
||||||
.map_err(|err| RogError::Path(MODPROBE_PATH.into(), err))?;
|
.map_err(|err| RogError::Path(MODPROBE_PATH.into(), err))?;
|
||||||
|
|
||||||
file.write_all(content)
|
file.write_all(&content)
|
||||||
.and_then(|_| file.sync_all())
|
.and_then(|_| file.sync_all())
|
||||||
.map_err(|err| RogError::Write(MODPROBE_PATH.into(), err))?;
|
.map_err(|err| RogError::Write(MODPROBE_PATH.into(), err))?;
|
||||||
|
|
||||||
@@ -258,34 +291,16 @@ impl CtrlGraphics {
|
|||||||
fn unbind_remove_nvidia(devices: &[GraphicsDevice]) -> Result<(), RogError> {
|
fn unbind_remove_nvidia(devices: &[GraphicsDevice]) -> Result<(), RogError> {
|
||||||
// Unbind NVIDIA graphics devices and their functions
|
// Unbind NVIDIA graphics devices and their functions
|
||||||
let unbinds = devices.iter().map(|dev| dev.unbind());
|
let unbinds = devices.iter().map(|dev| dev.unbind());
|
||||||
|
|
||||||
// Remove NVIDIA graphics devices and their functions
|
// Remove NVIDIA graphics devices and their functions
|
||||||
let removes = devices.iter().map(|dev| dev.remove());
|
let removes = devices.iter().map(|dev| dev.remove());
|
||||||
|
|
||||||
Result::from_iter(unbinds.chain(removes))
|
Result::from_iter(unbinds.chain(removes))
|
||||||
.map_err(|err| RogError::Command("device unbind error".into(), err))?;
|
.map_err(|err| RogError::Command("device unbind error".into(), err))
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_uses_of_nvidia() {
|
fn unbind_only(devices: &[GraphicsDevice]) -> Result<(), RogError> {
|
||||||
// lsof /dev/nvidia*
|
let unbinds = devices.iter().map(|dev| dev.unbind());
|
||||||
let mut cmd = Command::new("lsof");
|
Result::from_iter(unbinds)
|
||||||
cmd.arg("/dev/nvidia*");
|
.map_err(|err| RogError::Command("device unbind error".into(), err))
|
||||||
|
|
||||||
match cmd.output() {
|
|
||||||
Ok(output) => {
|
|
||||||
if !output.status.success() {
|
|
||||||
error!(
|
|
||||||
"Failed to list uses of nvidia devices: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
);
|
|
||||||
} else if output.status.success() {
|
|
||||||
warn!("GFX: {}", String::from_utf8_lossy(&output.stdout));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => error!("GFX: Failed to list uses of nvidia devices: {}", err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_driver_action(driver: &str, action: &str) -> Result<(), RogError> {
|
fn do_driver_action(driver: &str, action: &str) -> Result<(), RogError> {
|
||||||
@@ -312,14 +327,13 @@ impl CtrlGraphics {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if output.stderr.ends_with("Permission denied\n".as_bytes()) {
|
if output.stderr.ends_with("Permission denied\n".as_bytes()) {
|
||||||
let msg = format!(
|
warn!(
|
||||||
"{} {} failed: {:?}",
|
"{} {} failed: {:?}",
|
||||||
action,
|
action,
|
||||||
driver,
|
driver,
|
||||||
String::from_utf8_lossy(&output.stderr)
|
String::from_utf8_lossy(&output.stderr)
|
||||||
);
|
);
|
||||||
warn!("GFX: {}", msg);
|
warn!("GFX: It may be safe to ignore the above error, run `lsmod |grep {}` to confirm modules loaded", driver);
|
||||||
warn!("GFX: It may be safe to ignore the above error, run `lsmod |grep nvidia` to confirm modules loaded");
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if count >= MAX_TRIES {
|
if count >= MAX_TRIES {
|
||||||
@@ -378,6 +392,20 @@ impl CtrlGraphics {
|
|||||||
Err(GfxError::DisplayManagerTimeout(state.into()).into())
|
Err(GfxError::DisplayManagerTimeout(state.into()).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determine if we need to logout/thread. Integrated<->Vfio mode does not
|
||||||
|
/// require logout.
|
||||||
|
fn logout_required(&self, vendor: GfxVendors) -> GfxRequiredUserAction {
|
||||||
|
if let Ok(config) = self.config.lock() {
|
||||||
|
let current = config.gfx_mode;
|
||||||
|
if matches!(current, GfxVendors::Integrated | GfxVendors::Vfio)
|
||||||
|
&& matches!(vendor, GfxVendors::Integrated | GfxVendors::Vfio)
|
||||||
|
{
|
||||||
|
return GfxRequiredUserAction::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GfxRequiredUserAction::Logout
|
||||||
|
}
|
||||||
|
|
||||||
/// Write the config changes and add/remove drivers and devices depending
|
/// Write the config changes and add/remove drivers and devices depending
|
||||||
/// on selected mode:
|
/// on selected mode:
|
||||||
///
|
///
|
||||||
@@ -387,35 +415,40 @@ impl CtrlGraphics {
|
|||||||
/// - rescan for devices
|
/// - rescan for devices
|
||||||
/// + add drivers
|
/// + add drivers
|
||||||
/// + or remove drivers and devices
|
/// + or remove drivers and devices
|
||||||
|
///
|
||||||
|
/// The daemon needs direct access to this function when it detects that the
|
||||||
pub fn do_vendor_tasks(
|
pub fn do_vendor_tasks(
|
||||||
vendor: GfxVendors,
|
vendor: GfxVendors,
|
||||||
devices: &[GraphicsDevice],
|
devices: &[GraphicsDevice],
|
||||||
bus: &PciBus,
|
bus: &PciBus,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
|
// Rescan before doing remove or add drivers
|
||||||
|
bus.rescan()?;
|
||||||
|
//
|
||||||
Self::write_xorg_conf(vendor)?;
|
Self::write_xorg_conf(vendor)?;
|
||||||
// Write different modprobe to enable boot control to work
|
// Write different modprobe to enable boot control to work
|
||||||
match vendor {
|
Self::write_modprobe_conf(vendor, devices)?;
|
||||||
GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Compute => {
|
|
||||||
Self::write_modprobe_conf(MODPROBE_BASE)?
|
|
||||||
}
|
|
||||||
// GfxVendors::Compute => {}
|
|
||||||
GfxVendors::Integrated => Self::write_modprobe_conf(MODPROBE_INTEGRATED)?,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rescan before doing remove or add drivers
|
|
||||||
bus.rescan()
|
|
||||||
.map_err(|err| GfxError::Bus("bus rescan error".into(), err))?;
|
|
||||||
|
|
||||||
match vendor {
|
match vendor {
|
||||||
GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Compute => {
|
GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Compute => {
|
||||||
|
for driver in VFIO_DRIVERS.iter() {
|
||||||
|
Self::do_driver_action(driver, "rmmod")?;
|
||||||
|
}
|
||||||
for driver in NVIDIA_DRIVERS.iter() {
|
for driver in NVIDIA_DRIVERS.iter() {
|
||||||
Self::do_driver_action(driver, "modprobe").map_err(|err| {
|
Self::do_driver_action(driver, "modprobe")?;
|
||||||
Self::log_uses_of_nvidia();
|
|
||||||
err
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GfxVendors::Vfio => {
|
||||||
|
for driver in NVIDIA_DRIVERS.iter() {
|
||||||
|
Self::do_driver_action(driver, "rmmod")?;
|
||||||
|
}
|
||||||
|
Self::unbind_only(&devices)?;
|
||||||
|
Self::do_driver_action("vfio-pci", "modprobe")?;
|
||||||
|
}
|
||||||
GfxVendors::Integrated => {
|
GfxVendors::Integrated => {
|
||||||
|
for driver in VFIO_DRIVERS.iter() {
|
||||||
|
Self::do_driver_action(driver, "rmmod")?;
|
||||||
|
}
|
||||||
for driver in NVIDIA_DRIVERS.iter() {
|
for driver in NVIDIA_DRIVERS.iter() {
|
||||||
Self::do_driver_action(driver, "rmmod")?;
|
Self::do_driver_action(driver, "rmmod")?;
|
||||||
}
|
}
|
||||||
@@ -426,7 +459,7 @@ impl CtrlGraphics {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn graphical_session_active(
|
fn graphical_session_alive(
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
sessions: &[SessionInfo],
|
sessions: &[SessionInfo],
|
||||||
) -> Result<bool, RogError> {
|
) -> Result<bool, RogError> {
|
||||||
@@ -435,9 +468,9 @@ impl CtrlGraphics {
|
|||||||
if session_proxy.get_class()? == SessionClass::User {
|
if session_proxy.get_class()? == SessionClass::User {
|
||||||
match session_proxy.get_type()? {
|
match session_proxy.get_type()? {
|
||||||
SessionType::X11 | SessionType::Wayland | SessionType::MIR => {
|
SessionType::X11 | SessionType::Wayland | SessionType::MIR => {
|
||||||
if session_proxy.get_active()? {
|
//if session_proxy.get_active()? {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -452,6 +485,7 @@ impl CtrlGraphics {
|
|||||||
devices: Vec<GraphicsDevice>,
|
devices: Vec<GraphicsDevice>,
|
||||||
bus: PciBus,
|
bus: PciBus,
|
||||||
thread_stop: mpsc::Receiver<bool>,
|
thread_stop: mpsc::Receiver<bool>,
|
||||||
|
config: Arc<Mutex<Config>>,
|
||||||
) -> Result<String, RogError> {
|
) -> Result<String, RogError> {
|
||||||
info!("GFX: display-manager thread started");
|
info!("GFX: display-manager thread started");
|
||||||
|
|
||||||
@@ -470,7 +504,7 @@ impl CtrlGraphics {
|
|||||||
sessions = tmp;
|
sessions = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Self::graphical_session_active(&connection, &sessions)? {
|
if !Self::graphical_session_alive(&connection, &sessions)? {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +544,8 @@ impl CtrlGraphics {
|
|||||||
Self::do_display_manager_action("restart")?;
|
Self::do_display_manager_action("restart")?;
|
||||||
Self::wait_display_manager_state("active")?;
|
Self::wait_display_manager_state("active")?;
|
||||||
}
|
}
|
||||||
|
// Save selected mode in case of reboot
|
||||||
|
Self::save_gfx_mode(vendor, config);
|
||||||
info!("GFX: display-manager started");
|
info!("GFX: display-manager started");
|
||||||
|
|
||||||
let v: &str = vendor.into();
|
let v: &str = vendor.into();
|
||||||
@@ -517,18 +553,7 @@ impl CtrlGraphics {
|
|||||||
Ok(format!("Graphics mode changed to {} successfully", v))
|
Ok(format!("Graphics mode changed to {} successfully", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiates a mode change by starting a thread that will wait until all
|
fn cancel_thread(&self) {
|
||||||
/// graphical sessions are exited before performing the tasks required
|
|
||||||
/// to switch modes.
|
|
||||||
///
|
|
||||||
/// For manually calling (not on boot/startup) via dbus
|
|
||||||
pub fn set_gfx_config(&mut self, vendor: GfxVendors) -> Result<String, RogError> {
|
|
||||||
if let Ok(gsync) = CtrlRogBios::get_gfx_mode() {
|
|
||||||
if gsync == 1 {
|
|
||||||
return Err(GfxError::GsyncModeActive.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(lock) = self.thread_kill.lock() {
|
if let Ok(lock) = self.thread_kill.lock() {
|
||||||
if let Some(tx) = lock.as_ref() {
|
if let Some(tx) = lock.as_ref() {
|
||||||
// Cancel the running thread
|
// Cancel the running thread
|
||||||
@@ -540,7 +565,11 @@ impl CtrlGraphics {
|
|||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The thread is used only in cases where a logout is required
|
||||||
|
fn setup_thread(&mut self, vendor: GfxVendors) {
|
||||||
|
let config = self.config.clone();
|
||||||
let devices = self.nvidia.clone();
|
let devices = self.nvidia.clone();
|
||||||
let bus = self.bus.clone();
|
let bus = self.bus.clone();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
@@ -549,11 +578,8 @@ impl CtrlGraphics {
|
|||||||
}
|
}
|
||||||
let killer = self.thread_kill.clone();
|
let killer = self.thread_kill.clone();
|
||||||
|
|
||||||
// Save selected mode in case of reboot
|
|
||||||
Self::save_gfx_mode(vendor, self.config.clone());
|
|
||||||
|
|
||||||
let _join: JoinHandle<()> = std::thread::spawn(move || {
|
let _join: JoinHandle<()> = std::thread::spawn(move || {
|
||||||
Self::fire_starter(vendor, devices, bus, rx)
|
Self::fire_starter(vendor, devices, bus, rx, config)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
error!("GFX: {}", err);
|
error!("GFX: {}", err);
|
||||||
})
|
})
|
||||||
@@ -563,28 +589,42 @@ impl CtrlGraphics {
|
|||||||
*lock = None;
|
*lock = None;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: undo if failed? Save last mode, catch errors...
|
|
||||||
let v: &str = vendor.into();
|
|
||||||
Ok(format!("Graphics mode changed to {} successfully", v))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if CtrlRogBios::has_dedicated_gfx_toggle() {
|
/// Initiates a mode change by starting a thread that will wait until all
|
||||||
// if let Ok(config) = self.config.clone().try_lock() {
|
/// graphical sessions are exited before performing the tasks required
|
||||||
// // Switch to dedicated if config says to do so
|
/// to switch modes.
|
||||||
// if config.gfx_nv_mode_is_dedicated && vendor == GfxVendors::Nvidia {
|
///
|
||||||
// CtrlRogBios::set_gfx_mode(true)
|
/// For manually calling (not on boot/startup) via dbus
|
||||||
// .unwrap_or_else(|err| warn!("GFX: Gfx controller: {}", err));
|
pub fn set_gfx_config(
|
||||||
// } else if let Ok(ded) = CtrlRogBios::get_gfx_mode() {
|
&mut self,
|
||||||
// // otherwise if switching to non-Nvidia mode turn off dedicated mode
|
vendor: GfxVendors,
|
||||||
// if ded == 1 && vendor != GfxVendors::Nvidia {
|
) -> Result<GfxRequiredUserAction, RogError> {
|
||||||
// CtrlRogBios::set_gfx_mode(false)
|
if let Ok(gsync) = CtrlRogBios::get_gfx_mode() {
|
||||||
// .unwrap_or_else(|err| warn!("GFX: Gfx controller: {}", err));
|
if gsync == 1 {
|
||||||
// }
|
return Err(GfxError::GsyncModeActive.into());
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
// Must always cancel any thread running
|
||||||
|
self.cancel_thread();
|
||||||
|
// determine which method we need here
|
||||||
|
let action_required = self.logout_required(vendor);
|
||||||
|
if matches!(action_required, GfxRequiredUserAction::Logout) {
|
||||||
|
// Yeah need the thread to check if all users are logged out
|
||||||
|
info!("GFX: mode change requires a logout to complete");
|
||||||
|
self.setup_thread(vendor);
|
||||||
|
} else {
|
||||||
|
// Okay cool, we can switch on/off vfio
|
||||||
|
info!("GFX: mode change does not require logout");
|
||||||
|
let devices = self.nvidia.clone();
|
||||||
|
let bus = self.bus.clone();
|
||||||
|
Self::do_vendor_tasks(vendor, &devices, &bus)?;
|
||||||
|
}
|
||||||
|
// TODO: undo if failed? Save last mode, catch errors...
|
||||||
|
Ok(action_required)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used only on boot to set correct mode
|
||||||
fn auto_power(&mut self) -> Result<(), RogError> {
|
fn auto_power(&mut self) -> Result<(), RogError> {
|
||||||
let vendor = self.get_gfx_mode()?;
|
let vendor = self.get_gfx_mode()?;
|
||||||
let devices = self.nvidia.clone();
|
let devices = self.nvidia.clone();
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ pub mod system;
|
|||||||
|
|
||||||
const NVIDIA_DRIVERS: [&str; 4] = ["nvidia_drm", "nvidia_modeset", "nvidia_uvm", "nvidia"];
|
const NVIDIA_DRIVERS: [&str; 4] = ["nvidia_drm", "nvidia_modeset", "nvidia_uvm", "nvidia"];
|
||||||
|
|
||||||
|
const VFIO_DRIVERS: [&str; 5] = [
|
||||||
|
"vfio-pci",
|
||||||
|
"vfio_iommu_type1",
|
||||||
|
"vfio_virqfd",
|
||||||
|
"vfio_mdev",
|
||||||
|
"vfio",
|
||||||
|
];
|
||||||
|
|
||||||
const DISPLAY_MANAGER: &str = "display-manager.service";
|
const DISPLAY_MANAGER: &str = "display-manager.service";
|
||||||
|
|
||||||
const MODPROBE_PATH: &str = "/etc/modprobe.d/asusd.conf";
|
const MODPROBE_PATH: &str = "/etc/modprobe.d/asusd.conf";
|
||||||
@@ -30,6 +38,8 @@ blacklist nouveau
|
|||||||
alias nouveau off
|
alias nouveau off
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
static MODPROBE_VFIO: &[u8] = br#"options vfio-pci ids="#;
|
||||||
|
|
||||||
const XORG_FILE: &str = "90-nvidia-primary.conf";
|
const XORG_FILE: &str = "90-nvidia-primary.conf";
|
||||||
const XORG_PATH: &str = "/etc/X11/xorg.conf.d/";
|
const XORG_PATH: &str = "/etc/X11/xorg.conf.d/";
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ impl GraphicsDevice {
|
|||||||
self.functions.iter().any(|func| func.path().exists())
|
self.functions.iter().any(|func| func.path().exists())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn functions(&self) -> &[PciDevice] {
|
||||||
|
&self.functions
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unbind(&self) -> Result<(), std::io::Error> {
|
pub fn unbind(&self) -> Result<(), std::io::Error> {
|
||||||
for func in self.functions.iter() {
|
for func in self.functions.iter() {
|
||||||
if func.path().exists() {
|
if func.path().exists() {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub enum RogError {
|
|||||||
Initramfs(String),
|
Initramfs(String),
|
||||||
Modprobe(String),
|
Modprobe(String),
|
||||||
Command(String, std::io::Error),
|
Command(String, std::io::Error),
|
||||||
|
Io(std::io::Error),
|
||||||
Zbus(zbus::Error),
|
Zbus(zbus::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ impl fmt::Display for RogError {
|
|||||||
RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail),
|
RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail),
|
||||||
RogError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail),
|
RogError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail),
|
||||||
RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error),
|
RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error),
|
||||||
|
RogError::Io(detail) => write!(f, "std::io error: {}", detail),
|
||||||
RogError::Zbus(detail) => write!(f, "Zbus error: {}", detail),
|
RogError::Zbus(detail) => write!(f, "Zbus error: {}", detail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,3 +89,9 @@ impl From<zbus::Error> for RogError {
|
|||||||
RogError::Zbus(err)
|
RogError::Zbus(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for RogError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
RogError::Io(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ pub mod zbus_profile;
|
|||||||
pub mod zbus_rogbios;
|
pub mod zbus_rogbios;
|
||||||
pub mod zbus_supported;
|
pub mod zbus_supported;
|
||||||
|
|
||||||
use rog_types::aura_modes::AuraEffect;
|
use rog_types::{
|
||||||
|
aura_modes::AuraEffect,
|
||||||
|
gfx_vendors::{GfxRequiredUserAction, GfxVendors},
|
||||||
|
};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use zbus::{Connection, Result, SignalReceiver};
|
use zbus::{Connection, Result, SignalReceiver};
|
||||||
|
|
||||||
@@ -86,8 +89,8 @@ impl<'a> DbusProxies<'a> {
|
|||||||
|
|
||||||
// Signals separated out
|
// Signals separated out
|
||||||
pub struct Signals {
|
pub struct Signals {
|
||||||
pub gfx_vendor: Arc<Mutex<Option<String>>>,
|
pub gfx_vendor: Arc<Mutex<Option<GfxVendors>>>,
|
||||||
pub gfx_action: Arc<Mutex<Option<String>>>,
|
pub gfx_action: Arc<Mutex<Option<GfxRequiredUserAction>>>,
|
||||||
pub profile: Arc<Mutex<Option<String>>>,
|
pub profile: Arc<Mutex<Option<String>>>,
|
||||||
pub led_mode: Arc<Mutex<Option<AuraEffect>>>,
|
pub led_mode: Arc<Mutex<Option<AuraEffect>>>,
|
||||||
pub charge: Arc<Mutex<Option<u8>>>,
|
pub charge: Arc<Mutex<Option<u8>>>,
|
||||||
@@ -151,13 +154,13 @@ impl<'a> AuraDbusClient<'a> {
|
|||||||
/*
|
/*
|
||||||
* GFX
|
* GFX
|
||||||
*/
|
*/
|
||||||
pub fn gfx_wait_changed(&self) -> Result<String> {
|
pub fn gfx_wait_changed(&self) -> Result<GfxRequiredUserAction> {
|
||||||
loop {
|
loop {
|
||||||
if let Ok(res) = self.proxies.gfx.proxy().next_signal() {
|
if let Ok(res) = self.proxies.gfx.proxy().next_signal() {
|
||||||
if res.is_none() {
|
if res.is_none() {
|
||||||
if let Ok(lock) = self.signals.gfx_action.lock() {
|
if let Ok(lock) = self.signals.gfx_action.lock() {
|
||||||
if let Some(stuff) = lock.as_ref() {
|
if let Some(stuff) = lock.as_ref() {
|
||||||
return Ok(stuff.to_string());
|
return Ok(*stuff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// return Ok("Failed for unknown reason".to_owned());
|
// return Ok("Failed for unknown reason".to_owned());
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use rog_types::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
||||||
use zbus::{dbus_proxy, Connection, Result};
|
use zbus::{dbus_proxy, Connection, Result};
|
||||||
|
|
||||||
#[dbus_proxy(
|
#[dbus_proxy(
|
||||||
@@ -32,18 +33,18 @@ trait Daemon {
|
|||||||
fn power(&self) -> zbus::Result<String>;
|
fn power(&self) -> zbus::Result<String>;
|
||||||
|
|
||||||
/// SetVendor method
|
/// SetVendor method
|
||||||
fn set_vendor(&self, vendor: &str) -> zbus::Result<()>;
|
fn set_vendor(&self, vendor: &GfxVendors) -> zbus::Result<GfxRequiredUserAction>;
|
||||||
|
|
||||||
/// Vendor method
|
/// Vendor method
|
||||||
fn vendor(&self) -> zbus::Result<String>;
|
fn vendor(&self) -> zbus::Result<GfxVendors>;
|
||||||
|
|
||||||
/// NotifyAction signal
|
/// NotifyAction signal
|
||||||
#[dbus_proxy(signal)]
|
#[dbus_proxy(signal)]
|
||||||
fn notify_action(&self, action: &str) -> zbus::Result<()>;
|
fn notify_action(&self, action: GfxRequiredUserAction) -> zbus::Result<()>;
|
||||||
|
|
||||||
/// NotifyGfx signal
|
/// NotifyGfx signal
|
||||||
#[dbus_proxy(signal)]
|
#[dbus_proxy(signal)]
|
||||||
fn notify_gfx(&self, vendor: &str) -> zbus::Result<()>;
|
fn notify_gfx(&self, vendor: GfxVendors) -> zbus::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GfxProxy<'a>(DaemonProxy<'a>);
|
pub struct GfxProxy<'a>(DaemonProxy<'a>);
|
||||||
@@ -64,33 +65,36 @@ impl<'a> GfxProxy<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gfx_get_mode(&self) -> Result<String> {
|
pub fn gfx_get_mode(&self) -> Result<GfxVendors> {
|
||||||
self.0.vendor()
|
self.0.vendor()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gfx_write_mode(&self, vendor: &str) -> Result<()> {
|
pub fn gfx_write_mode(&self, vendor: &GfxVendors) -> Result<GfxRequiredUserAction> {
|
||||||
self.0.set_vendor(vendor)
|
self.0.set_vendor(vendor)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn connect_notify_action(
|
pub fn connect_notify_action(
|
||||||
&self,
|
&self,
|
||||||
action: Arc<Mutex<Option<String>>>,
|
action: Arc<Mutex<Option<GfxRequiredUserAction>>>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.0.connect_notify_action(move |data| {
|
self.0.connect_notify_action(move |data| {
|
||||||
if let Ok(mut lock) = action.lock() {
|
if let Ok(mut lock) = action.lock() {
|
||||||
*lock = Some(data.to_owned());
|
*lock = Some(data);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn connect_notify_gfx(&self, vendor: Arc<Mutex<Option<String>>>) -> zbus::fdo::Result<()> {
|
pub fn connect_notify_gfx(
|
||||||
|
&self,
|
||||||
|
vendor: Arc<Mutex<Option<GfxVendors>>>,
|
||||||
|
) -> zbus::fdo::Result<()> {
|
||||||
self.0.connect_notify_gfx(move |data| {
|
self.0.connect_notify_gfx(move |data| {
|
||||||
if let Ok(mut lock) = vendor.lock() {
|
if let Ok(mut lock) = vendor.lock() {
|
||||||
*lock = Some(data.to_owned());
|
*lock = Some(data);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ trait Daemon {
|
|||||||
fn set_led_mode(&self, effect: &AuraEffect) -> zbus::Result<()>;
|
fn set_led_mode(&self, effect: &AuraEffect) -> zbus::Result<()>;
|
||||||
|
|
||||||
/// NotifyLed signal
|
/// NotifyLed signal
|
||||||
/// NotifyLed signal
|
/// NotifyLed signal
|
||||||
#[dbus_proxy(signal)]
|
#[dbus_proxy(signal)]
|
||||||
fn notify_led(&self, data: &str) -> zbus::Result<()>;
|
fn notify_led(&self, data: &str) -> zbus::Result<()>;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
// static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
// static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
||||||
// static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
// static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
||||||
|
|
||||||
use crate::LED_MSG_LEN;
|
|
||||||
use crate::error::AuraError;
|
use crate::error::AuraError;
|
||||||
|
use crate::LED_MSG_LEN;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use zvariant_derive::Type;
|
use zvariant_derive::Type;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use crate::{
|
use crate::error::AuraError;
|
||||||
error::AuraError,
|
|
||||||
};
|
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use crate::error::GraphicsError;
|
use crate::error::GraphicsError;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use zvariant_derive::Type;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Type, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||||
pub enum GfxVendors {
|
pub enum GfxVendors {
|
||||||
Nvidia,
|
Nvidia,
|
||||||
Integrated,
|
Integrated,
|
||||||
Compute,
|
Compute,
|
||||||
|
Vfio,
|
||||||
Hybrid,
|
Hybrid,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,10 +20,12 @@ impl FromStr for GfxVendors {
|
|||||||
"nvidia" => Ok(GfxVendors::Nvidia),
|
"nvidia" => Ok(GfxVendors::Nvidia),
|
||||||
"hybrid" => Ok(GfxVendors::Hybrid),
|
"hybrid" => Ok(GfxVendors::Hybrid),
|
||||||
"compute" => Ok(GfxVendors::Compute),
|
"compute" => Ok(GfxVendors::Compute),
|
||||||
|
"vfio" => Ok(GfxVendors::Vfio),
|
||||||
"integrated" => Ok(GfxVendors::Integrated),
|
"integrated" => Ok(GfxVendors::Integrated),
|
||||||
"nvidia\n" => Ok(GfxVendors::Nvidia),
|
"nvidia\n" => Ok(GfxVendors::Nvidia),
|
||||||
"hybrid\n" => Ok(GfxVendors::Hybrid),
|
"hybrid\n" => Ok(GfxVendors::Hybrid),
|
||||||
"compute\n" => Ok(GfxVendors::Compute),
|
"compute\n" => Ok(GfxVendors::Compute),
|
||||||
|
"vfio\n" => Ok(GfxVendors::Vfio),
|
||||||
"integrated\n" => Ok(GfxVendors::Integrated),
|
"integrated\n" => Ok(GfxVendors::Integrated),
|
||||||
_ => Err(GraphicsError::ParseVendor),
|
_ => Err(GraphicsError::ParseVendor),
|
||||||
}
|
}
|
||||||
@@ -34,6 +38,7 @@ impl From<&GfxVendors> for &str {
|
|||||||
GfxVendors::Nvidia => "nvidia",
|
GfxVendors::Nvidia => "nvidia",
|
||||||
GfxVendors::Hybrid => "hybrid",
|
GfxVendors::Hybrid => "hybrid",
|
||||||
GfxVendors::Compute => "compute",
|
GfxVendors::Compute => "compute",
|
||||||
|
GfxVendors::Vfio => "vfio",
|
||||||
GfxVendors::Integrated => "integrated",
|
GfxVendors::Integrated => "integrated",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,38 +50,19 @@ impl From<GfxVendors> for &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Type, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||||
pub enum GfxCtrlAction {
|
pub enum GfxRequiredUserAction {
|
||||||
|
Logout,
|
||||||
Reboot,
|
Reboot,
|
||||||
RestartX,
|
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for GfxCtrlAction {
|
impl From<&GfxRequiredUserAction> for &str {
|
||||||
type Err = GraphicsError;
|
fn from(gfx: &GfxRequiredUserAction) -> &'static str {
|
||||||
|
match gfx {
|
||||||
fn from_str(s: &str) -> Result<Self, GraphicsError> {
|
GfxRequiredUserAction::Logout => "logout",
|
||||||
match s.to_lowercase().as_str() {
|
GfxRequiredUserAction::Reboot => "reboot",
|
||||||
"reboot" => Ok(GfxCtrlAction::Reboot),
|
GfxRequiredUserAction::None => "no action",
|
||||||
"restartx" => Ok(GfxCtrlAction::RestartX),
|
|
||||||
"none" => Ok(GfxCtrlAction::None),
|
|
||||||
_ => Err(GraphicsError::ParseVendor),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&GfxCtrlAction> for &str {
|
|
||||||
fn from(mode: &GfxCtrlAction) -> Self {
|
|
||||||
match mode {
|
|
||||||
GfxCtrlAction::Reboot => "reboot",
|
|
||||||
GfxCtrlAction::RestartX => "restartx",
|
|
||||||
GfxCtrlAction::None => "none",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<GfxCtrlAction> for &str {
|
|
||||||
fn from(mode: GfxCtrlAction) -> Self {
|
|
||||||
(&mode).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user