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:
+19
-5
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user