diff --git a/drivers/pcid/src/driver_interface/bar.rs b/drivers/pcid/src/driver_interface/bar.rs index d398ca4281..28aade48d6 100644 --- a/drivers/pcid/src/driver_interface/bar.rs +++ b/drivers/pcid/src/driver_interface/bar.rs @@ -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"), } } diff --git a/drivers/pcid/src/driver_interface/irq_helpers.rs b/drivers/pcid/src/driver_interface/irq_helpers.rs index 28ca077a92..69ccaff26a 100644 --- a/drivers/pcid/src/driver_interface/irq_helpers.rs +++ b/drivers/pcid/src/driver_interface/irq_helpers.rs @@ -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 { + 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"), + )) + } +} diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs index fa5adf65b2..21622caa03 100644 --- a/drivers/pcid/src/driver_interface/mod.rs +++ b/drivers/pcid/src/driver_interface/mod.rs @@ -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::()) + .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: F) -> ! { diff --git a/drivers/virtio-core/src/probe.rs b/drivers/virtio-core/src/probe.rs index bd656932af..eaef1b96f4 100644 --- a/drivers/virtio-core/src/probe.rs +++ b/drivers/virtio-core/src/probe.rs @@ -57,7 +57,7 @@ pub fn probe_device(pcid_handle: &mut PciFunctionHandle) -> Result