Only try to load drivers for endpoint functions

For bridge functions we don't have any existing drivers and we
currently panic if we would try to load a driver for them.
This commit is contained in:
bjorn3
2024-01-22 18:03:46 +01:00
parent 545596f296
commit 623d12f276
2 changed files with 42 additions and 37 deletions
+19 -5
View File
@@ -16,7 +16,7 @@ use crate::config::Config;
use crate::pci::{PciBar, PciFunc};
use crate::pci::cap::Capability as PciCapability;
use crate::pci::func::{ConfigReader, ConfigWriter};
use crate::pci_header::{PciHeader, PciHeaderError};
use crate::pci_header::{PciEndpointHeader, PciHeader, PciHeaderError};
mod cfg_access;
mod config;
@@ -206,7 +206,7 @@ pub struct State {
pcie: Pcie,
}
fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, header: PciHeader) {
fn print_pci_function(addr: PciAddress, header: &PciHeader) {
let mut string = format!("PCI {} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}",
addr, header.vendor_id(), header.device_id(), header.class(),
header.subclass(), header.interface(), header.revision(), header.class());
@@ -229,7 +229,9 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, he
_ => (),
}
info!("{}", string);
}
fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, header: PciEndpointHeader) {
for driver in config.drivers.iter() {
if !driver.match_function(header.full_device_id()) {
continue;
@@ -470,9 +472,21 @@ fn main(args: Args) {
let func_addr = PciAddress::new(0, bus_num, dev_num, func_num);
match PciHeader::from_reader(&state.pcie, func_addr) {
Ok(header) => {
handle_parsed_header(Arc::clone(&state), &config, func_addr, header);
if let PciHeader::PciToPci { secondary_bus_num, .. } = header {
bus_nums.push(secondary_bus_num);
print_pci_function(func_addr, &header);
match header {
PciHeader::General(endpoint_header) => {
handle_parsed_header(
Arc::clone(&state),
&config,
func_addr,
endpoint_header,
);
}
PciHeader::PciToPci {
secondary_bus_num, ..
} => {
bus_nums.push(secondary_bus_num);
}
}
}
Err(PciHeaderError::NoDevice) => {
+23 -32
View File
@@ -21,14 +21,17 @@ pub struct SharedPciHeader {
addr: PciAddress,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PciEndpointHeader {
shared: SharedPciHeader,
subsystem_vendor_id: u16,
subsystem_id: u16,
cap_pointer: u8,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PciHeader {
General {
shared: SharedPciHeader,
subsystem_vendor_id: u16,
subsystem_id: u16,
cap_pointer: u8,
},
General(PciEndpointHeader),
PciToPci {
shared: SharedPciHeader,
secondary_bus_num: u8,
@@ -73,12 +76,12 @@ impl PciHeader {
let endpoint_header = EndpointHeader::from_header(header, access).unwrap();
let (subsystem_id, subsystem_vendor_id) = endpoint_header.subsystem(access);
let cap_pointer = (unsafe { access.read(addr, 0x34) } & 0xff) as u8;
Ok(PciHeader::General {
Ok(PciHeader::General(PciEndpointHeader {
shared,
subsystem_vendor_id,
subsystem_id,
cap_pointer,
})
}))
}
HeaderType::PciPciBridge => {
let bridge_header = PciPciBridgeHeader::from_header(header, access).unwrap();
@@ -97,14 +100,14 @@ impl PciHeader {
/// Return all identifying information of the PCI function.
pub fn full_device_id(&self) -> &FullDeviceId {
match self {
PciHeader::General {
PciHeader::General(PciEndpointHeader {
shared:
SharedPciHeader {
full_device_id: device_id,
..
},
..
}
})
| PciHeader::PciToPci {
shared:
SharedPciHeader {
@@ -145,17 +148,18 @@ impl PciHeader {
pub fn class(&self) -> u8 {
self.full_device_id().class
}
}
impl PciEndpointHeader {
pub fn full_device_id(&self) -> &FullDeviceId {
&self.shared.full_device_id
}
/// Return the Headers BARs.
// FIXME use pci_types::Bar instead
pub fn bars(&self, access: &impl ConfigRegionAccess) -> [PciBar; 6] {
let endpoint_header = match *self {
PciHeader::General {
shared: SharedPciHeader { addr, .. },
..
} => EndpointHeader::from_header(TyPciHeader::new(addr), access).unwrap(),
PciHeader::PciToPci { .. } => unreachable!(),
};
let endpoint_header =
EndpointHeader::from_header(TyPciHeader::new(self.shared.addr), access).unwrap();
let mut bars = [PciBar::None; 6];
let mut skip = false;
@@ -196,24 +200,11 @@ impl PciHeader {
}
pub fn status(&self) -> u16 {
match self {
&PciHeader::General {
shared: SharedPciHeader { status, .. },
..
}
| &PciHeader::PciToPci {
shared: SharedPciHeader { status, .. },
..
} => status,
}
self.shared.status
}
pub fn cap_pointer(&self) -> u8 {
match self {
&PciHeader::General { cap_pointer, .. } | &PciHeader::PciToPci { cap_pointer, .. } => {
cap_pointer
}
}
self.cap_pointer
}
}