diff --git a/pcid/src/config.rs b/pcid/src/config.rs index 83faddd586..6c79e7eb63 100644 --- a/pcid/src/config.rs +++ b/pcid/src/config.rs @@ -3,6 +3,8 @@ use std::ops::Range; use serde::Deserialize; +use crate::pci::PciHeader; + #[derive(Clone, Debug, Default, Deserialize)] pub struct Config { pub drivers: Vec, @@ -20,3 +22,69 @@ pub struct DriverConfig { pub device_id_range: Option>, pub command: Option>, } + +impl DriverConfig { + pub fn match_function(&self, header: &PciHeader) -> bool { + if let Some(class) = self.class { + if class != header.class().into() { + return false; + } + } + + if let Some(subclass) = self.subclass { + if subclass != header.subclass() { + return false; + } + } + + if let Some(interface) = self.interface { + if interface != header.interface() { + return false; + } + } + + if let Some(ref ids) = self.ids { + let mut device_found = false; + for (vendor, devices) in ids { + let vendor_without_prefix = vendor.trim_start_matches("0x"); + let vendor = i64::from_str_radix(vendor_without_prefix, 16).unwrap() as u16; + + if vendor != header.vendor_id() { + continue; + } + + for device in devices { + if *device == header.device_id() { + device_found = true; + break; + } + } + } + if !device_found { + return false; + } + } else { + if let Some(vendor) = self.vendor { + if vendor != header.vendor_id() { + return false; + } + } + + if let Some(device) = self.device { + if device != header.device_id() { + return false; + } + } + } + + if let Some(ref device_id_range) = self.device_id_range { + if header.device_id() < device_id_range.start + || device_id_range.end <= header.device_id() + { + return false; + } + } + + true + } +} diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 048b9cf03d..8e762dca09 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -2,8 +2,8 @@ use std::fs::{File, metadata, read_dir}; use std::io::prelude::*; use std::os::unix::io::{FromRawFd, RawFd}; use std::process::Command; +use std::thread; use std::sync::{Arc, Mutex}; -use std::{i64, thread}; use structopt::StructOpt; use log::{debug, error, info, warn, trace}; @@ -265,47 +265,8 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he info!("{}", string); for driver in config.drivers.iter() { - if let Some(class) = driver.class { - if class != raw_class { continue; } - } - - if let Some(subclass) = driver.subclass { - if subclass != header.subclass() { continue; } - } - - if let Some(interface) = driver.interface { - if interface != header.interface() { continue; } - } - - if let Some(ref ids) = driver.ids { - let mut device_found = false; - for (vendor, devices) in ids { - let vendor_without_prefix = vendor.trim_start_matches("0x"); - let vendor = i64::from_str_radix(vendor_without_prefix, 16).unwrap() as u16; - - if vendor != header.vendor_id() { continue; } - - for device in devices { - if *device == header.device_id() { - device_found = true; - break; - } - } - } - if !device_found { continue; } - } else { - if let Some(vendor) = driver.vendor { - if vendor != header.vendor_id() { continue; } - } - - if let Some(device) = driver.device { - if device != header.device_id() { continue; } - } - } - - if let Some(ref device_id_range) = driver.device_id_range { - if header.device_id() < device_id_range.start || - device_id_range.end <= header.device_id() { continue; } + if !driver.match_function(&header) { + continue; } if let Some(ref args) = driver.command {