use crate::PciInfoError;
use super::{
pci_config_buffer::PciConfigBuffer, pci_generic_device_header::PciGenericDeviceHeader,
pci_to_cardbus_bridge_header::PciToCardbusBridgeHeader,
pci_to_pci_bridge_header::PciToPciBridgeHeader, PciCommonHeader,
};
#[derive(Clone, Debug)]
pub enum PciSpecializedHeader {
GenericDevice(PciGenericDeviceHeader),
PciToPciBridge(PciToPciBridgeHeader),
PciToCardbusBridge(PciToCardbusBridgeHeader),
}
impl PciSpecializedHeader {
pub fn length_of_subheader(header_type: u8) -> Option<usize> {
match header_type & 0x7F {
PciGenericDeviceHeader::ID => Some(PciGenericDeviceHeader::LENGTH),
PciToPciBridgeHeader::ID => Some(PciToPciBridgeHeader::LENGTH),
PciToCardbusBridgeHeader::ID => Some(PciToCardbusBridgeHeader::LENGTH),
_ => None,
}
}
pub fn read_subheader(
header_type: u8,
bytes: &[u8],
includes_common_header: bool,
) -> Result<Self, PciInfoError> {
let bytes_offset = if includes_common_header {
0
} else {
PciCommonHeader::COMMON_HEADER_LEN
};
let pci_cfg = PciConfigBuffer::new(bytes, bytes_offset);
match header_type & 0x7F {
PciGenericDeviceHeader::ID => Ok(PciSpecializedHeader::GenericDevice(
PciGenericDeviceHeader::with_pci_cfg(&pci_cfg)?,
)),
PciToPciBridgeHeader::ID => Ok(PciSpecializedHeader::PciToPciBridge(
PciToPciBridgeHeader::with_pci_cfg(&pci_cfg)?,
)),
PciToCardbusBridgeHeader::ID => Ok(PciSpecializedHeader::PciToCardbusBridge(
PciToCardbusBridgeHeader::with_pci_cfg(&pci_cfg)?,
)),
_ => Err(PciInfoError::UnknownPciHeaderType(header_type)),
}
}
}