Add "info" output for gfx driver check

This commit is contained in:
Luke D Jones
2020-09-22 09:52:22 +12:00
parent d4702a166a
commit 368d279ca5
15 changed files with 319 additions and 135 deletions

View File

@@ -14,8 +14,8 @@ use crate::{error::GfxError, system::*};
pub struct CtrlGraphics {
bus: PciBus,
amd: Vec<GraphicsDevice>,
intel: Vec<GraphicsDevice>,
_amd: Vec<GraphicsDevice>,
_intel: Vec<GraphicsDevice>,
nvidia: Vec<GraphicsDevice>,
#[allow(dead_code)]
other: Vec<GraphicsDevice>,
@@ -23,6 +23,8 @@ pub struct CtrlGraphics {
}
trait Dbus {
fn vendor(&self) -> String;
fn power(&self) -> String;
fn set_vendor(&mut self, vendor: String);
fn notify_gfx(&self, vendor: &str) -> zbus::Result<()>;
fn notify_action(&self, action: &str) -> zbus::Result<()>;
@@ -34,6 +36,18 @@ use std::convert::TryInto;
#[cfg(feature = "use-zbus")]
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl Dbus for CtrlGraphics {
fn vendor(&self) -> String {
Self::get_vendor()
.map_err(|err| format!("Get vendor failed: {}", err))
.unwrap()
}
fn power(&self) -> String {
Self::get_runtime_status()
.map_err(|err| format!("Get power status failed: {}", err))
.unwrap()
}
fn set_vendor(&mut self, vendor: String) {
if let Ok(tmp) = GfxVendors::from_str(&vendor) {
let action = self.set(tmp).unwrap_or_else(|err| {
@@ -113,17 +127,18 @@ impl CtrlGraphics {
cmd.arg("-u");
initfs_cmd = Some(cmd);
info!("Using initramfs update command 'update-initramfs'");
} else if Path::new(DRACUT_PATH).exists() {
let mut cmd = Command::new("dracut");
cmd.arg("-f");
initfs_cmd = Some(cmd);
info!("Using initramfs update command 'dracut'");
}
// } else if Path::new(DRACUT_PATH).exists() {
// let mut cmd = Command::new("dracut");
// cmd.arg("-f");
// initfs_cmd = Some(cmd);
// info!("Using initramfs update command 'dracut'");
// }
Ok(CtrlGraphics {
bus,
amd,
intel,
_amd: amd,
_intel: intel,
nvidia,
other,
initfs_cmd,
@@ -143,9 +158,9 @@ impl CtrlGraphics {
Ok(())
}
fn can_switch(&self) -> bool {
!self.nvidia.is_empty() && (!self.intel.is_empty() || !self.amd.is_empty())
}
// fn can_switch(&self) -> bool {
// !self.nvidia.is_empty() && (!self.intel.is_empty() || !self.amd.is_empty())
// }
fn get_prime_discrete() -> Result<String, GfxError> {
let s = std::fs::read_to_string(PRIME_DISCRETE_PATH)
@@ -168,6 +183,7 @@ impl CtrlGraphics {
.iter()
.any(|module| module.name == "nouveau" || module.name == "nvidia")
{
info!("nvidia or nouveau module found");
let mode = match Self::get_prime_discrete() {
Ok(m) => m,
Err(_) => "nvidia".to_string(),
@@ -181,6 +197,7 @@ impl CtrlGraphics {
"nvidia".to_string()
}
} else {
info!("No dGPU driver (nouveau or nvidia) loaded");
"integrated".to_string()
};
@@ -212,10 +229,10 @@ impl CtrlGraphics {
// Switching from hybrid to/from nvidia shouldn't require a ramdisk update
// or a reboot.
let switching_prime_modes = Self::is_switching_prime_modes(&vendor)?;
let no_reboot = Self::is_switching_prime_modes(&vendor)?;
{
info!("Creating {}", MODPROBE_PATH);
info!("Writing {}", MODPROBE_PATH);
let mut file = std::fs::OpenOptions::new()
.create(true)
@@ -239,7 +256,7 @@ impl CtrlGraphics {
.map_err(|err| GfxError::Write(MODPROBE_PATH.into(), err))?;
}
info!("Creating {}", PRIMARY_GPU_XORG_PATH);
info!("Writing {}", PRIMARY_GPU_XORG_PATH);
// begin section for non-separated Nvidia xorg modules
// eg, not put in their own directory
@@ -283,7 +300,7 @@ impl CtrlGraphics {
}
let mut required_action = GfxCtrlAction::None;
if !switching_prime_modes {
if !no_reboot {
info!("Updating initramfs");
if let Some(cmd) = self.initfs_cmd.as_mut() {
let status = cmd
@@ -296,18 +313,24 @@ impl CtrlGraphics {
}
}
required_action = GfxCtrlAction::Reboot;
} else if switching_prime_modes {
} else if no_reboot {
required_action = GfxCtrlAction::RestartX;
}
Ok(required_action.into())
}
pub fn get_power(&self) -> Option<bool> {
if self.can_switch() {
return Some(self.nvidia.iter().any(GraphicsDevice::exists));
}
None
// pub fn get_power(&self) -> Option<bool> {
// if self.can_switch() {
// return Some(self.nvidia.iter().any(GraphicsDevice::exists));
// }
// None
// }
pub fn get_runtime_status() -> Result<String, GfxError> {
const PATH: &str = "/sys/bus/pci/devices/0000:01:00.0/power/runtime_status";
let buf = std::fs::read_to_string(PATH)
.map_err(|err| GfxError::Read(PATH.into(), err))?;
Ok(buf)
}
fn set_power(&self, power: bool) -> Result<(), GfxError> {

View File

@@ -9,7 +9,7 @@ pub mod system;
const PRIME_DISCRETE_PATH: &str = "/etc/prime-discrete";
const MODPROBE_PATH: &str = "/etc/modprobe.d/asusd.conf";
const INITRAMFS_PATH: &str = "/usr/sbin/update-initramfs";
const DRACUT_PATH: &str = "/usr/bin/dracut";
//const DRACUT_PATH: &str = "/usr/bin/dracut";
static MODPROBE_NVIDIA: &[u8] = MODPROBE_HYBRID;
@@ -54,4 +54,5 @@ static PRIMARY_GPU_NVIDIA: &[u8] = br#"
Option "PrimaryGPU" "true""#;
static PRIMARY_GPU_END: &[u8] = br#"
EndSection"#;
EndSection"#;