fix: add try_map_bar, try_pci_allocate_interrupt_vector, fix try_mem return type
- try_mem now returns Result (matching caller expectations) - try_map_bar: non-panicking BAR mapping on PciFunctionHandle - try_pci_allocate_interrupt_vector: non-panicking IRQ allocation - virtio-core: reverted .ok_or() back to .map_err() for Result type
This commit is contained in:
@@ -53,16 +53,17 @@ impl PciBar {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_mem(&self) -> Option<(usize, usize)> {
|
||||
pub fn try_mem(&self) -> Result<(usize, usize), &'static str> {
|
||||
match *self {
|
||||
PciBar::Memory32 { addr, size } => Some((addr as usize, size as usize)),
|
||||
PciBar::Memory64 { addr, size } => Some((
|
||||
PciBar::Memory32 { addr, size } => Ok((addr as usize, size as usize)),
|
||||
PciBar::Memory64 { addr, size } => Ok((
|
||||
addr.try_into()
|
||||
.expect("conversion from 64bit BAR to usize failed"),
|
||||
size.try_into()
|
||||
.expect("conversion from 64bit BAR size to usize failed"),
|
||||
)),
|
||||
_ => None,
|
||||
PciBar::Port(_) => Err("expected memory BAR, found port BAR"),
|
||||
PciBar::None => Err("expected BAR to exist"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -332,3 +332,27 @@ pub fn pci_allocate_interrupt_vector(
|
||||
panic!("{driver}: no interrupts supported at all")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_pci_allocate_interrupt_vector(
|
||||
pcid_handle: &mut crate::driver_interface::PciFunctionHandle,
|
||||
driver: &str,
|
||||
) -> io::Result<InterruptVector> {
|
||||
let features = pcid_handle.fetch_all_features();
|
||||
let has_msi = features.iter().any(|feature| feature.is_msi());
|
||||
let has_msix = features.iter().any(|feature| feature.is_msix());
|
||||
|
||||
if has_msix || has_msi {
|
||||
Ok(pci_allocate_interrupt_vector(pcid_handle, driver))
|
||||
} else if let Some(irq) = pcid_handle.config().func.legacy_interrupt_line {
|
||||
Ok(InterruptVector {
|
||||
irq_handle: irq.try_irq_handle(driver)?,
|
||||
vector: 0,
|
||||
kind: InterruptVectorKind::Legacy,
|
||||
})
|
||||
} else {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
format!("{driver}: no interrupts supported at all"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,6 +508,33 @@ impl PciFunctionHandle {
|
||||
})
|
||||
}
|
||||
}
|
||||
pub unsafe fn try_map_bar(&mut self, bir: u8) -> Result<&MappedBar, String> {
|
||||
let mapped_bar = &mut self.mapped_bars[bir as usize];
|
||||
if mapped_bar.is_none() {
|
||||
let (bar, bar_size) = self.config.func.bars[bir as usize]
|
||||
.try_mem()
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let ptr = unsafe {
|
||||
common::physmap(
|
||||
bar,
|
||||
bar_size,
|
||||
common::Prot::RW,
|
||||
common::MemoryType::Uncacheable,
|
||||
)
|
||||
}
|
||||
.map_err(|e| format!("physmap failed: {e}"))?;
|
||||
|
||||
let ptr = NonNull::new(ptr.cast::<u8>())
|
||||
.ok_or_else(|| "physmap returned null".to_string())?;
|
||||
|
||||
mapped_bar.insert(MappedBar {
|
||||
ptr,
|
||||
bar_size,
|
||||
});
|
||||
}
|
||||
Ok(mapped_bar.as_ref().expect("BAR was just mapped"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pci_daemon<F: FnOnce(Daemon, PciFunctionHandle) -> !>(f: F) -> ! {
|
||||
|
||||
@@ -57,7 +57,7 @@ pub fn probe_device(pcid_handle: &mut PciFunctionHandle) -> Result<Device, Error
|
||||
|
||||
let (addr, _) = pci_config.func.bars[capability.bar as usize]
|
||||
.try_mem()
|
||||
.ok_or(Error::Probe("BAR is not memory-mapped"))?;
|
||||
.map_err(|_| Error::Probe("BAR is not memory-mapped"))?;
|
||||
|
||||
let address = unsafe {
|
||||
let addr = addr + capability.offset as usize;
|
||||
|
||||
Reference in New Issue
Block a user