From fd3cf798840dcbbcd5610c4aa3fe9c017b71fef5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 9 Jun 2024 19:07:38 +0200 Subject: [PATCH 1/3] pcid: Move spawning and interacting with subdrivers out of main.rs --- pcid/src/driver_handler.rs | 331 +++++++++++++++++++++++++++++++++++++ pcid/src/main.rs | 217 +----------------------- 2 files changed, 334 insertions(+), 214 deletions(-) create mode 100644 pcid/src/driver_handler.rs diff --git a/pcid/src/driver_handler.rs b/pcid/src/driver_handler.rs new file mode 100644 index 0000000000..60c893dd85 --- /dev/null +++ b/pcid/src/driver_handler.rs @@ -0,0 +1,331 @@ +use std::fs::File; +use std::os::unix::io::{FromRawFd, RawFd}; +use std::process::Command; +use std::sync::Arc; +use std::thread; + +use log::{error, info}; +use pci_types::PciAddress; + +use crate::driver_interface; +use crate::pci::cap::Capability as PciCapability; +use crate::pci::PciFunc; +use crate::State; + +pub struct DriverHandler { + addr: PciAddress, + capabilities: Vec<(u8, PciCapability)>, + + state: Arc, +} + +impl DriverHandler { + pub fn spawn( + state: Arc, + func: driver_interface::PciFunction, + capabilities: Vec<(u8, PciCapability)>, + args: &[String], + ) { + let subdriver_args = driver_interface::SubdriverArguments { func }; + + let mut args = args.iter(); + if let Some(program) = args.next() { + let mut command = Command::new(program); + for arg in args { + if arg.starts_with("$") { + panic!("support for $VARIABLE has been removed. use pcid_interface instead"); + } + command.arg(arg); + } + + info!("PCID SPAWN {:?}", command); + + // TODO: libc wrapper? + let [fds1, fds2] = unsafe { + let mut fds1 = [0 as libc::c_int; 2]; + let mut fds2 = [0 as libc::c_int; 2]; + + assert_eq!( + libc::pipe(fds1.as_mut_ptr()), + 0, + "pcid: failed to create pcid->client pipe" + ); + assert_eq!( + libc::pipe(fds2.as_mut_ptr()), + 0, + "pcid: failed to create client->pcid pipe" + ); + + [fds1.map(|c| c as usize), fds2.map(|c| c as usize)] + }; + + let [pcid_to_client_read, pcid_to_client_write] = fds1; + let [pcid_from_client_read, pcid_from_client_write] = fds2; + + let envs = vec![ + ("PCID_TO_CLIENT_FD", format!("{}", pcid_to_client_read)), + ("PCID_FROM_CLIENT_FD", format!("{}", pcid_from_client_write)), + ]; + + match command.envs(envs).spawn() { + Ok(mut child) => { + let driver_handler = DriverHandler { + addr: func.addr, + state, + capabilities, + }; + let _handle = thread::spawn(move || { + driver_handler.handle_spawn( + pcid_to_client_write, + pcid_from_client_read, + subdriver_args, + ); + }); + // FIXME this currently deadlocks as pcid doesn't daemonize + //state.threads.lock().unwrap().push(handle); + match child.wait() { + Ok(_status) => (), + Err(err) => error!("pcid: failed to wait for {:?}: {}", command, err), + } + } + Err(err) => error!("pcid: failed to execute {:?}: {}", command, err), + } + } + } + + fn respond( + &mut self, + request: driver_interface::PcidClientRequest, + args: &driver_interface::SubdriverArguments, + ) -> driver_interface::PcidClientResponse { + use crate::pci::cap::{MsiCapability, MsixCapability}; + use driver_interface::*; + + let func = PciFunc { + pci: &self.state.pcie, + addr: self.addr, + }; + + match request { + PcidClientRequest::RequestCapabilities => PcidClientResponse::Capabilities( + self.capabilities + .iter() + .map(|(_, capability)| capability.clone()) + .collect::>(), + ), + PcidClientRequest::RequestConfig => PcidClientResponse::Config(args.clone()), + PcidClientRequest::RequestFeatures => PcidClientResponse::AllFeatures( + self.capabilities + .iter() + .filter_map(|(_, capability)| match capability { + PciCapability::Msi(msi) => { + Some((PciFeature::Msi, FeatureStatus::enabled(msi.enabled()))) + } + PciCapability::MsiX(msix) => Some(( + PciFeature::MsiX, + FeatureStatus::enabled(msix.msix_enabled()), + )), + _ => None, + }) + .collect(), + ), + PcidClientRequest::EnableFeature(feature) => match feature { + PciFeature::Msi => { + let (offset, capability): (u8, &mut MsiCapability) = match self + .capabilities + .iter_mut() + .find_map(|&mut (offset, ref mut capability)| { + capability.as_msi_mut().map(|cap| (offset, cap)) + }) { + Some(tuple) => tuple, + None => { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(feature), + ) + } + }; + unsafe { + capability.set_enabled(true); + capability.write_message_control(&func, offset); + } + PcidClientResponse::FeatureEnabled(feature) + } + PciFeature::MsiX => { + let (offset, capability): (u8, &mut MsixCapability) = match self + .capabilities + .iter_mut() + .find_map(|&mut (offset, ref mut capability)| { + capability.as_msix_mut().map(|cap| (offset, cap)) + }) { + Some(tuple) => tuple, + None => { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(feature), + ) + } + }; + unsafe { + capability.set_msix_enabled(true); + capability.write_a(&func, offset); + } + PcidClientResponse::FeatureEnabled(feature) + } + }, + PcidClientRequest::FeatureStatus(feature) => PcidClientResponse::FeatureStatus( + feature, + match feature { + PciFeature::Msi => self + .capabilities + .iter() + .find_map(|(_, capability)| { + if let PciCapability::Msi(msi) = capability { + Some(FeatureStatus::enabled(msi.enabled())) + } else { + None + } + }) + .unwrap_or(FeatureStatus::Disabled), + PciFeature::MsiX => self + .capabilities + .iter() + .find_map(|(_, capability)| { + if let PciCapability::MsiX(msix) = capability { + Some(FeatureStatus::enabled(msix.msix_enabled())) + } else { + None + } + }) + .unwrap_or(FeatureStatus::Disabled), + }, + ), + PcidClientRequest::FeatureInfo(feature) => PcidClientResponse::FeatureInfo( + feature, + match feature { + PciFeature::Msi => { + if let Some(info) = self + .capabilities + .iter() + .find_map(|(_, capability)| capability.as_msi()) + { + PciFeatureInfo::Msi(*info) + } else { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(feature), + ); + } + } + PciFeature::MsiX => { + if let Some(info) = self + .capabilities + .iter() + .find_map(|(_, capability)| capability.as_msix()) + { + PciFeatureInfo::MsiX(*info) + } else { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(feature), + ); + } + } + }, + ), + PcidClientRequest::SetFeatureInfo(info_to_set) => match info_to_set { + SetFeatureInfo::Msi(info_to_set) => { + if let Some((offset, info)) = self + .capabilities + .iter_mut() + .find_map(|(offset, capability)| Some((*offset, capability.as_msi_mut()?))) + { + if let Some(mme) = info_to_set.multi_message_enable { + if info.multi_message_capable() < mme || mme > 0b101 { + return PcidClientResponse::Error( + PcidServerResponseError::InvalidBitPattern, + ); + } + info.set_multi_message_enable(mme); + } + if let Some(message_addr_and_data) = info_to_set.message_address_and_data { + let message_addr = message_addr_and_data.addr; + if message_addr & 0b11 != 0 { + return PcidClientResponse::Error( + PcidServerResponseError::InvalidBitPattern, + ); + } + info.set_message_address(message_addr as u32); + info.set_message_upper_address((message_addr >> 32) as u32); + if message_addr_and_data.data & ((1 << info.multi_message_enable()) - 1) + != 0 + { + return PcidClientResponse::Error( + PcidServerResponseError::InvalidBitPattern, + ); + } + info.set_message_data( + message_addr_and_data + .data + .try_into() + .expect("pcid: MSI message data too big"), + ); + } + if let Some(mask_bits) = info_to_set.mask_bits { + info.set_mask_bits(mask_bits); + } + unsafe { + info.write_all(&func, offset); + } + PcidClientResponse::SetFeatureInfo(PciFeature::Msi) + } else { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(PciFeature::Msi), + ); + } + } + SetFeatureInfo::MsiX { function_mask } => { + if let Some((offset, info)) = self + .capabilities + .iter_mut() + .find_map(|(offset, capability)| Some((*offset, capability.as_msix_mut()?))) + { + if let Some(mask) = function_mask { + info.set_function_mask(mask); + unsafe { + info.write_a(&func, offset); + } + } + PcidClientResponse::SetFeatureInfo(PciFeature::MsiX) + } else { + return PcidClientResponse::Error( + PcidServerResponseError::NonexistentFeature(PciFeature::MsiX), + ); + } + } + }, + PcidClientRequest::ReadConfig(offset) => { + let value = unsafe { func.read_u32(offset) }; + return PcidClientResponse::ReadConfig(value); + } + PcidClientRequest::WriteConfig(offset, value) => { + unsafe { + func.write_u32(offset, value); + } + return PcidClientResponse::WriteConfig; + } + } + } + fn handle_spawn( + mut self, + pcid_to_client_write: usize, + pcid_from_client_read: usize, + args: driver_interface::SubdriverArguments, + ) { + use driver_interface::*; + + let mut pcid_to_client = unsafe { File::from_raw_fd(pcid_to_client_write as RawFd) }; + let mut pcid_from_client = unsafe { File::from_raw_fd(pcid_from_client_read as RawFd) }; + + while let Ok(msg) = recv(&mut pcid_from_client) { + let response = self.respond(msg, &args); + send(&mut pcid_to_client, &response).unwrap(); + } + } +} diff --git a/pcid/src/main.rs b/pcid/src/main.rs index f5d146632f..5ee29bc3e3 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -1,24 +1,22 @@ 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 pci_types::{CommandRegister, PciAddress}; use structopt::StructOpt; -use log::{debug, error, info, warn, trace}; +use log::{debug, info, warn, trace}; use redox_log::{OutputBuilder, RedoxLogger}; use crate::cfg_access::Pcie; use crate::config::Config; use crate::driver_interface::LegacyInterruptLine; use crate::pci::PciFunc; -use crate::pci::cap::Capability as PciCapability; use crate::pci_header::{PciEndpointHeader, PciHeader, PciHeaderError}; mod cfg_access; mod config; +mod driver_handler; mod driver_interface; mod pci; mod pci_header; @@ -35,158 +33,6 @@ struct Args { config_path: Option, } -pub struct DriverHandler { - addr: PciAddress, - capabilities: Vec<(u8, PciCapability)>, - - state: Arc, -} - -impl DriverHandler { - fn respond(&mut self, request: driver_interface::PcidClientRequest, args: &driver_interface::SubdriverArguments) -> driver_interface::PcidClientResponse { - use driver_interface::*; - use crate::pci::cap::{MsiCapability, MsixCapability}; - - let func = PciFunc { - pci: &self.state.pcie, - addr: self.addr, - }; - - match request { - PcidClientRequest::RequestCapabilities => { - PcidClientResponse::Capabilities(self.capabilities.iter().map(|(_, capability)| capability.clone()).collect::>()) - } - PcidClientRequest::RequestConfig => { - PcidClientResponse::Config(args.clone()) - } - PcidClientRequest::RequestFeatures => { - PcidClientResponse::AllFeatures(self.capabilities.iter().filter_map(|(_, capability)| match capability { - PciCapability::Msi(msi) => Some((PciFeature::Msi, FeatureStatus::enabled(msi.enabled()))), - PciCapability::MsiX(msix) => Some((PciFeature::MsiX, FeatureStatus::enabled(msix.msix_enabled()))), - _ => None, - }).collect()) - } - PcidClientRequest::EnableFeature(feature) => match feature { - PciFeature::Msi => { - let (offset, capability): (u8, &mut MsiCapability) = match self.capabilities.iter_mut().find_map(|&mut (offset, ref mut capability)| capability.as_msi_mut().map(|cap| (offset, cap))) { - Some(tuple) => tuple, - None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)), - }; - unsafe { - capability.set_enabled(true); - capability.write_message_control(&func, offset); - } - PcidClientResponse::FeatureEnabled(feature) - } - PciFeature::MsiX => { - let (offset, capability): (u8, &mut MsixCapability) = match self.capabilities.iter_mut().find_map(|&mut (offset, ref mut capability)| capability.as_msix_mut().map(|cap| (offset, cap))) { - Some(tuple) => tuple, - None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)), - }; - unsafe { - capability.set_msix_enabled(true); - capability.write_a(&func, offset); - } - PcidClientResponse::FeatureEnabled(feature) - } - } - PcidClientRequest::FeatureStatus(feature) => PcidClientResponse::FeatureStatus(feature, match feature { - PciFeature::Msi => self.capabilities.iter().find_map(|(_, capability)| if let PciCapability::Msi(msi) = capability { - Some(FeatureStatus::enabled(msi.enabled())) - } else { - None - }).unwrap_or(FeatureStatus::Disabled), - PciFeature::MsiX => self.capabilities.iter().find_map(|(_, capability)| if let PciCapability::MsiX(msix) = capability { - Some(FeatureStatus::enabled(msix.msix_enabled())) - } else { - None - }).unwrap_or(FeatureStatus::Disabled), - }), - PcidClientRequest::FeatureInfo(feature) => PcidClientResponse::FeatureInfo(feature, match feature { - PciFeature::Msi => if let Some(info) = self.capabilities.iter().find_map(|(_, capability)| capability.as_msi()) { - PciFeatureInfo::Msi(*info) - } else { - return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)); - } - PciFeature::MsiX => if let Some(info) = self.capabilities.iter().find_map(|(_, capability)| capability.as_msix()) { - PciFeatureInfo::MsiX(*info) - } else { - return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)); - } - }), - PcidClientRequest::SetFeatureInfo(info_to_set) => match info_to_set { - SetFeatureInfo::Msi(info_to_set) => if let Some((offset, info)) = self.capabilities.iter_mut().find_map(|(offset, capability)| Some((*offset, capability.as_msi_mut()?))) { - if let Some(mme) = info_to_set.multi_message_enable { - if info.multi_message_capable() < mme || mme > 0b101 { - return PcidClientResponse::Error(PcidServerResponseError::InvalidBitPattern); - } - info.set_multi_message_enable(mme); - - } - if let Some(message_addr_and_data) = info_to_set.message_address_and_data { - let message_addr = message_addr_and_data.addr; - if message_addr & 0b11 != 0 { - return PcidClientResponse::Error(PcidServerResponseError::InvalidBitPattern); - } - info.set_message_address(message_addr as u32); - info.set_message_upper_address((message_addr >> 32) as u32); - if message_addr_and_data.data & ((1 << info.multi_message_enable()) - 1) != 0 { - return PcidClientResponse::Error(PcidServerResponseError::InvalidBitPattern); - } - info.set_message_data( - message_addr_and_data - .data - .try_into() - .expect("pcid: MSI message data too big"), - ); - } - if let Some(mask_bits) = info_to_set.mask_bits { - info.set_mask_bits(mask_bits); - } - unsafe { - info.write_all(&func, offset); - } - PcidClientResponse::SetFeatureInfo(PciFeature::Msi) - } else { - return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(PciFeature::Msi)); - } - SetFeatureInfo::MsiX { function_mask } => if let Some((offset, info)) = self.capabilities.iter_mut().find_map(|(offset, capability)| Some((*offset, capability.as_msix_mut()?))) { - if let Some(mask) = function_mask { - info.set_function_mask(mask); - unsafe { - info.write_a(&func, offset); - } - } - PcidClientResponse::SetFeatureInfo(PciFeature::MsiX) - } else { - return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(PciFeature::MsiX)); - } - } - PcidClientRequest::ReadConfig(offset) => { - let value = unsafe { func.read_u32(offset) }; - return PcidClientResponse::ReadConfig(value); - }, - PcidClientRequest::WriteConfig(offset, value) => { - unsafe { - func.write_u32(offset, value); - } - return PcidClientResponse::WriteConfig; - } - } - } - fn handle_spawn(mut self, pcid_to_client_write: usize, pcid_from_client_read: usize, args: driver_interface::SubdriverArguments) { - use driver_interface::*; - - let mut pcid_to_client = unsafe { File::from_raw_fd(pcid_to_client_write as RawFd) }; - let mut pcid_from_client = unsafe { File::from_raw_fd(pcid_from_client_read as RawFd) }; - - while let Ok(msg) = recv(&mut pcid_from_client) { - let response = self.respond(msg, &args); - send(&mut pcid_to_client, &response).unwrap(); - } - } -} - pub struct State { threads: Mutex>>, pcie: Pcie, @@ -268,64 +114,7 @@ fn handle_parsed_header(state: Arc, config: &Config, header: PciEndpointH full_device_id: header.full_device_id().clone(), }; - let subdriver_args = driver_interface::SubdriverArguments { - func, - }; - - let mut args = args.iter(); - if let Some(program) = args.next() { - let mut command = Command::new(program); - for arg in args { - if arg.starts_with("$") { - panic!("support for $VARIABLE has been removed. use pcid_interface instead"); - } - command.arg(arg); - } - - info!("PCID SPAWN {:?}", command); - - // TODO: libc wrapper? - let [fds1, fds2] = unsafe { - let mut fds1 = [0 as libc::c_int; 2]; - let mut fds2 = [0 as libc::c_int; 2]; - - assert_eq!(libc::pipe(fds1.as_mut_ptr()), 0, "pcid: failed to create pcid->client pipe"); - assert_eq!(libc::pipe(fds2.as_mut_ptr()), 0, "pcid: failed to create client->pcid pipe"); - - [ - fds1.map(|c| c as usize), - fds2.map(|c| c as usize), - ] - }; - - let [pcid_to_client_read, pcid_to_client_write] = fds1; - let [pcid_from_client_read, pcid_from_client_write] = fds2; - - let envs = vec![ - ("PCID_TO_CLIENT_FD", format!("{}", pcid_to_client_read)), - ("PCID_FROM_CLIENT_FD", format!("{}", pcid_from_client_write)), - ]; - - match command.envs(envs).spawn() { - Ok(mut child) => { - let driver_handler = DriverHandler { - addr: header.address(), - state: Arc::clone(&state), - capabilities, - }; - let _handle = thread::spawn(move || { - driver_handler.handle_spawn(pcid_to_client_write, pcid_from_client_read, subdriver_args); - }); - // FIXME this currently deadlocks as pcid doesn't daemonize - //state.threads.lock().unwrap().push(handle); - match child.wait() { - Ok(_status) => (), - Err(err) => error!("pcid: failed to wait for {:?}: {}", command, err), - } - } - Err(err) => error!("pcid: failed to execute {:?}: {}", command, err) - } - } + driver_handler::DriverHandler::spawn(Arc::clone(&state), func, capabilities, args); } } From 8f9bbecd0cdbeffc2fa8e8b29b3f5951a76c1302 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 9 Jun 2024 19:08:12 +0200 Subject: [PATCH 2/3] pcid: Rustfmt main.rs --- pcid/src/main.rs | 78 +++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 5ee29bc3e3..648a291a4c 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -1,12 +1,12 @@ -use std::fs::{File, metadata, read_dir}; +use std::fs::{metadata, read_dir, File}; use std::io::prelude::*; -use std::thread; use std::sync::{Arc, Mutex}; +use std::thread; +use log::{debug, info, trace, warn}; use pci_types::{CommandRegister, PciAddress}; -use structopt::StructOpt; -use log::{debug, info, warn, trace}; use redox_log::{OutputBuilder, RedoxLogger}; +use structopt::StructOpt; use crate::cfg_access::Pcie; use crate::config::Config; @@ -24,12 +24,17 @@ mod pci_header; #[derive(StructOpt)] #[structopt(about)] struct Args { - #[structopt(short, long, - help="Increase logging level once for each arg.", parse(from_occurrences))] + #[structopt( + short, + long, + help = "Increase logging level once for each arg.", + parse(from_occurrences) + )] verbose: u8, #[structopt( - help="A path to a pcid config file or a directory that contains pcid config files.")] + help = "A path to a pcid config file or a directory that contains pcid config files." + )] config_path: Option, } @@ -101,7 +106,14 @@ fn handle_parsed_header(state: Arc, config: &Config, header: PciEndpointH } else { Vec::new() }; - debug!("PCI DEVICE CAPABILITIES for {}: {:?}", args.iter().map(|string| string.as_ref()).nth(0).unwrap_or("[unknown]"), capabilities); + debug!( + "PCI DEVICE CAPABILITIES for {}: {:?}", + args.iter() + .map(|string| string.as_ref()) + .nth(0) + .unwrap_or("[unknown]"), + capabilities + ); let func = driver_interface::PciFunction { bars, @@ -124,31 +136,35 @@ fn setup_logging(verbosity: u8) -> Option<&'static RedoxLogger> { 1 => log::LevelFilter::Debug, _ => log::LevelFilter::Trace, }; - let mut logger = RedoxLogger::new() - .with_output( - OutputBuilder::stderr() - .with_ansi_escape_codes() - .with_filter(log_level) - .flush_on_newline(true) - .build() - ); + let mut logger = RedoxLogger::new().with_output( + OutputBuilder::stderr() + .with_ansi_escape_codes() + .with_filter(log_level) + .flush_on_newline(true) + .build(), + ); - #[cfg(target_os = "redox")] { + #[cfg(target_os = "redox")] + { match OutputBuilder::in_redox_logging_scheme("bus", "pci", "pcid.log") { - Ok(b) => logger = logger.with_output( - b.with_filter(log::LevelFilter::Trace) - .flush_on_newline(true) - .build() - ), + Ok(b) => { + logger = logger.with_output( + b.with_filter(log::LevelFilter::Trace) + .flush_on_newline(true) + .build(), + ) + } Err(error) => eprintln!("pcid: failed to open pcid.log"), } match OutputBuilder::in_redox_logging_scheme("bus", "pci", "pcid.ansi.log") { - Ok(b) => logger = logger.with_output( - b.with_filter(log::LevelFilter::Trace) - .with_ansi_escape_codes() - .flush_on_newline(true) - .build() - ), + Ok(b) => { + logger = logger.with_output( + b.with_filter(log::LevelFilter::Trace) + .with_ansi_escape_codes() + .flush_on_newline(true) + .build(), + ) + } Err(error) => eprintln!("pcid: failed to open pcid.ansi.log"), } } @@ -231,10 +247,10 @@ fn main(args: Args) { } Err(PciHeaderError::NoDevice) => { if func_addr.function() == 0 { - trace!("PCI {:>02X}:{:>02X}: no dev", bus_num, dev_num); - continue 'dev; + trace!("PCI {:>02X}:{:>02X}: no dev", bus_num, dev_num); + continue 'dev; } - }, + } Err(PciHeaderError::UnknownHeaderType(id)) => { warn!("pcid: unknown header type: {id:?}"); } From 027d952c39e600e7af168363087663a0124a952b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 9 Jun 2024 19:35:04 +0200 Subject: [PATCH 3/3] pcid: Remove parsing of unused capabilities This will make it easier to switch to pci_types for capability parsing in the future. --- pcid/src/pci/cap.rs | 72 ++++++--------------------------------------- 1 file changed, 9 insertions(+), 63 deletions(-) diff --git a/pcid/src/pci/cap.rs b/pcid/src/pci/cap.rs index 729845ef84..21ce506f00 100644 --- a/pcid/src/pci/cap.rs +++ b/pcid/src/pci/cap.rs @@ -83,32 +83,6 @@ pub enum MsiCapability { }, } - -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct PcieCapability { - pub pcie_caps: u32, - pub dev_caps: u32, - pub dev_sts_ctl: u32, - pub link_caps: u32, - pub link_sts_ctl: u32, - pub slot_caps: u32, - pub slot_sts_ctl: u32, - pub root_cap_ctl: u32, - pub root_sts: u32, - pub dev_caps2: u32, - pub dev_sts_ctl2: u32, - pub link_caps2: u32, - pub link_sts_ctl2: u32, - pub slot_caps2: u32, - pub slot_sts_ctl2: u32, -} - -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct PwrMgmtCapability { - pub a: u32, - pub b: u32, -} - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct MsixCapability { pub a: u32, @@ -125,10 +99,7 @@ pub struct VendorSpecificCapability { pub enum Capability { Msi(MsiCapability), MsiX(MsixCapability), - Pcie(PcieCapability), - PwrMgmt(PwrMgmtCapability), Vendor(VendorSpecificCapability), - FunctionSpecific(u8, Vec), // TODO: Arrayvec Other(u8), } @@ -167,12 +138,6 @@ impl Capability { c: func.read_u32(u16::from(offset + 8)), }) } - unsafe fn parse_pwr(func: &PciFunc, offset: u8) -> Self { - Self::PwrMgmt(PwrMgmtCapability { - a: func.read_u32(u16::from(offset)), - b: func.read_u32(u16::from(offset + 4)), - }) - } unsafe fn parse_vendor(func: &PciFunc, offset: u8) -> Self { let next = func.read_u8(u16::from(offset+1)); let length = func.read_u8(u16::from(offset+2)); @@ -188,27 +153,6 @@ impl Capability { data }) } - unsafe fn parse_pcie(func: &PciFunc, offset: u8) -> Self { - let offset = u16::from(offset); - - Self::Pcie(PcieCapability { - pcie_caps: func.read_u32(offset), - dev_caps: func.read_u32(offset + 0x04), - dev_sts_ctl: func.read_u32(offset + 0x08), - link_caps: func.read_u32(offset + 0x0C), - link_sts_ctl: func.read_u32(offset + 0x10), - slot_caps: func.read_u32(offset + 0x14), - slot_sts_ctl: func.read_u32(offset + 0x18), - root_cap_ctl: func.read_u32(offset + 0x1C), - root_sts: func.read_u32(offset + 0x20), - dev_caps2: func.read_u32(offset + 0x24), - dev_sts_ctl2: func.read_u32(offset + 0x28), - link_caps2: func.read_u32(offset + 0x2C), - link_sts_ctl2: func.read_u32(offset + 0x30), - slot_caps2: func.read_u32(offset + 0x34), - slot_sts_ctl2: func.read_u32(offset + 0x38), - }) - } unsafe fn parse(func: &PciFunc, offset: u8) -> Self { assert_eq!(offset & 0xFC, offset, "capability must be dword aligned"); @@ -219,16 +163,18 @@ impl Capability { Self::parse_msi(func, offset) } else if capability_id == CapabilityId::MsiX as u8 { Self::parse_msix(func, offset) - } else if capability_id == CapabilityId::Pcie as u8 { - Self::parse_pcie(func, offset) - } else if capability_id == CapabilityId::PwrMgmt as u8{ - Self::parse_pwr(func, offset) } else if capability_id == CapabilityId::Vendor as u8 { Self::parse_vendor(func, offset) - } else if capability_id == CapabilityId::Sata as u8 { - Self::FunctionSpecific(capability_id, func.read_range(offset.into(), 8)) } else { - log::warn!("unimplemented or malformed capability id: {}", capability_id); + if capability_id != CapabilityId::Pcie as u8 + && capability_id != CapabilityId::PwrMgmt as u8 + && capability_id != CapabilityId::Sata as u8 + { + log::warn!( + "unimplemented or malformed capability id: {}", + capability_id + ); + } Self::Other(capability_id) } }