sysfs_class/pci_bus/
mod.rs

1use crate::{RuntimePM, RuntimePowerManagement, SysClass};
2use std::fs;
3use std::io;
4use std::path::{Path, PathBuf};
5
6#[derive(Clone)]
7pub struct PciDriver {
8    path: PathBuf,
9}
10
11impl SysClass for PciDriver {
12    fn base() -> &'static str {
13        "bus"
14    }
15
16    fn class() -> &'static str {
17        "pci/drivers"
18    }
19
20    unsafe fn from_path_unchecked(path: PathBuf) -> Self {
21        Self { path }
22    }
23
24    fn path(&self) -> &Path {
25        &self.path
26    }
27}
28
29impl PciDriver {
30    pub unsafe fn bind(&self, device: &PciDevice) -> io::Result<()> {
31        self.write_file("bind", device.id())
32    }
33
34    pub unsafe fn unbind(&self, device: &PciDevice) -> io::Result<()> {
35        self.write_file("unbind", device.id())
36    }
37}
38
39macro_rules! pci_devices {
40    ($( fn $file:tt -> $out:tt; )*) => {
41        $(
42            pub fn $file(&self) -> io::Result<$out> {
43                let v = self.read_file(stringify!($file))?;
44                $out::from_str_radix(v[2..].trim(), 16).map_err(|err| {
45                    io::Error::new(
46                        io::ErrorKind::InvalidData,
47                        format!("{}", err)
48                    )
49                })
50            }
51        )*
52    }
53}
54
55#[derive(Clone)]
56pub struct PciDevice {
57    path: PathBuf,
58}
59
60impl SysClass for PciDevice {
61    fn base() -> &'static str {
62        "bus"
63    }
64
65    fn class() -> &'static str {
66        "pci/devices"
67    }
68
69    unsafe fn from_path_unchecked(path: PathBuf) -> Self {
70        Self { path }
71    }
72
73    fn path(&self) -> &Path {
74        &self.path
75    }
76}
77
78impl PciDevice {
79    pci_devices! {
80        fn class -> u32;
81        fn device -> u16;
82        fn revision -> u8;
83        fn subsystem_device -> u16;
84        fn subsystem_vendor -> u16;
85        fn vendor -> u16;
86    }
87
88    pub fn driver(&self) -> io::Result<PciDriver> {
89        fs::canonicalize(self.path.join("driver")).map(|path| PciDriver { path })
90    }
91
92    pub unsafe fn remove(&self) -> io::Result<()> {
93        self.write_file("remove", "1")
94    }
95}
96
97impl RuntimePM for PciDevice {
98    fn set_runtime_pm(&self, state: RuntimePowerManagement) -> io::Result<()> {
99        self.write_file("power/control", <&'static str>::from(state))
100    }
101}