Make all parsing in PciHeader::from_reader use pci_types
This commit is contained in:
+10
-58
@@ -1,9 +1,9 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use pci_types::{
|
||||
Bar as TyBar, ConfigRegionAccess, EndpointHeader, PciAddress, PciHeader as TyPciHeader,
|
||||
PciPciBridgeHeader,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -41,7 +41,6 @@ pub struct SharedPciHeader {
|
||||
addr: PciAddress,
|
||||
}
|
||||
|
||||
// FIXME move out of pcid_interface
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PciHeader {
|
||||
General {
|
||||
@@ -49,16 +48,11 @@ pub enum PciHeader {
|
||||
subsystem_vendor_id: u16,
|
||||
subsystem_id: u16,
|
||||
cap_pointer: u8,
|
||||
interrupt_line: u8,
|
||||
interrupt_pin: u8,
|
||||
},
|
||||
PciToPci {
|
||||
shared: SharedPciHeader,
|
||||
secondary_bus_num: u8,
|
||||
cap_pointer: u8,
|
||||
interrupt_line: u8,
|
||||
interrupt_pin: u8,
|
||||
bridge_control: u16,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -100,65 +94,29 @@ impl PciHeader {
|
||||
match header_type & PciHeaderType::HEADER_TYPE {
|
||||
PciHeaderType::GENERAL => {
|
||||
let endpoint_header = EndpointHeader::from_header(header, access).unwrap();
|
||||
let bytes = unsafe {
|
||||
let mut ret = Vec::with_capacity(48);
|
||||
for offset in (16..64).step_by(4) {
|
||||
ret.extend(access.read(addr, offset).to_le_bytes());
|
||||
}
|
||||
ret
|
||||
};
|
||||
let (subsystem_id, subsystem_vendor_id) = endpoint_header.subsystem(access);
|
||||
let cap_pointer = bytes[36];
|
||||
let (interrupt_pin, interrupt_line) = endpoint_header.interrupt(access);
|
||||
let cap_pointer = (unsafe { access.read(addr, 0x34) } & 0xff) as u8;
|
||||
Ok(PciHeader::General {
|
||||
shared,
|
||||
subsystem_vendor_id,
|
||||
subsystem_id,
|
||||
cap_pointer,
|
||||
interrupt_line,
|
||||
interrupt_pin,
|
||||
})
|
||||
}
|
||||
PciHeaderType::PCITOPCI => {
|
||||
let bytes = unsafe {
|
||||
let mut ret = Vec::with_capacity(48);
|
||||
for offset in (16..64).step_by(4) {
|
||||
ret.extend(access.read(addr, offset).to_le_bytes());
|
||||
}
|
||||
ret
|
||||
};
|
||||
let secondary_bus_num = bytes[9];
|
||||
let cap_pointer = bytes[36];
|
||||
let interrupt_line = bytes[44];
|
||||
let interrupt_pin = bytes[45];
|
||||
let bridge_control = LittleEndian::read_u16(&bytes[46..48]);
|
||||
let bridge_header = PciPciBridgeHeader::from_header(header, access).unwrap();
|
||||
let secondary_bus_num = bridge_header.secondary_bus_number(access);
|
||||
let cap_pointer = (unsafe { access.read(addr, 0x34) } & 0xff) as u8;
|
||||
Ok(PciHeader::PciToPci {
|
||||
shared,
|
||||
secondary_bus_num,
|
||||
cap_pointer,
|
||||
interrupt_line,
|
||||
interrupt_pin,
|
||||
bridge_control,
|
||||
})
|
||||
}
|
||||
id => Err(PciHeaderError::UnknownHeaderType(id.bits())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the Header Type.
|
||||
pub fn header_type(&self) -> PciHeaderType {
|
||||
match self {
|
||||
&PciHeader::General {
|
||||
shared: SharedPciHeader { header_type, .. },
|
||||
..
|
||||
}
|
||||
| &PciHeader::PciToPci {
|
||||
shared: SharedPciHeader { header_type, .. },
|
||||
..
|
||||
} => header_type,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return all identifying information of the PCI function.
|
||||
pub fn full_device_id(&self) -> &FullDeviceId {
|
||||
match self {
|
||||
@@ -260,14 +218,6 @@ impl PciHeader {
|
||||
bars
|
||||
}
|
||||
|
||||
/// Return the Interrupt Line field.
|
||||
pub fn interrupt_line(&self) -> u8 {
|
||||
match self {
|
||||
&PciHeader::General { interrupt_line, .. }
|
||||
| &PciHeader::PciToPci { interrupt_line, .. } => interrupt_line,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(&self) -> u16 {
|
||||
match self {
|
||||
&PciHeader::General {
|
||||
@@ -296,7 +246,7 @@ mod test {
|
||||
|
||||
use pci_types::{ConfigRegionAccess, PciAddress};
|
||||
|
||||
use super::{PciHeader, PciHeaderError, PciHeaderType};
|
||||
use super::{PciHeader, PciHeaderError};
|
||||
use crate::pci::PciClass;
|
||||
|
||||
struct TestCfgAccess<'a> {
|
||||
@@ -351,14 +301,16 @@ mod test {
|
||||
PciAddress::new(0, 2, 4, 0),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(header.header_type(), PciHeaderType::GENERAL);
|
||||
match header {
|
||||
PciHeader::General { .. } => {}
|
||||
_ => panic!("wrong header type"),
|
||||
}
|
||||
assert_eq!(header.device_id(), 0x1533);
|
||||
assert_eq!(header.vendor_id(), 0x8086);
|
||||
assert_eq!(header.revision(), 3);
|
||||
assert_eq!(header.interface(), 0);
|
||||
assert_eq!(header.class(), PciClass::Network);
|
||||
assert_eq!(header.subclass(), 0);
|
||||
assert_eq!(header.interrupt_line(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user