|
@@ -6,17 +6,16 @@ use crate::driver::pci::pci::{
|
|
|
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
|
|
};
|
|
|
|
|
|
-use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
|
|
|
use crate::driver::pci::root::pci_root_0;
|
|
|
|
|
|
use crate::exception::IrqNumber;
|
|
|
|
|
|
+use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
|
|
use crate::libs::volatile::{
|
|
|
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
|
|
};
|
|
|
use crate::mm::VirtAddr;
|
|
|
|
|
|
-use alloc::string::ToString;
|
|
|
use alloc::sync::Arc;
|
|
|
use core::{
|
|
|
fmt::{self, Display, Formatter},
|
|
@@ -28,7 +27,6 @@ use virtio_drivers::{
|
|
|
Error, Hal, PhysAddr,
|
|
|
};
|
|
|
|
|
|
-use super::irq::DefaultVirtioIrqHandler;
|
|
|
use super::VIRTIO_VENDOR_ID;
|
|
|
|
|
|
/// The offset to add to a VirtIO device ID to get the corresponding PCI device ID.
|
|
@@ -104,6 +102,7 @@ pub struct PciTransport {
|
|
|
config_space: Option<NonNull<[u32]>>,
|
|
|
irq: IrqNumber,
|
|
|
dev_id: Arc<DeviceId>,
|
|
|
+ device: Arc<SpinLock<PciDeviceStructureGeneralDevice>>,
|
|
|
}
|
|
|
|
|
|
impl PciTransport {
|
|
@@ -140,21 +139,7 @@ impl PciTransport {
|
|
|
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
|
|
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
|
|
irq_vector.push(irq);
|
|
|
- standard_device
|
|
|
- .irq_init(IRQ::PCI_IRQ_MSIX | IRQ::PCI_IRQ_MSI)
|
|
|
- .ok_or(VirtioPciError::UnableToInitIrq)?;
|
|
|
- // 中断相关信息
|
|
|
- let msg = PciIrqMsg {
|
|
|
- irq_common_message: IrqCommonMsg::init_from(
|
|
|
- 0,
|
|
|
- "Virtio_IRQ".to_string(),
|
|
|
- &DefaultVirtioIrqHandler,
|
|
|
- dev_id.clone(),
|
|
|
- ),
|
|
|
- irq_specific_message: IrqSpecificMsg::msi_default(),
|
|
|
- };
|
|
|
- standard_device.irq_install(msg)?;
|
|
|
- standard_device.irq_enable(true)?;
|
|
|
+
|
|
|
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
|
|
for capability in device.capabilities().unwrap() {
|
|
|
if capability.id != PCI_CAP_ID_VNDR {
|
|
@@ -236,8 +221,17 @@ impl PciTransport {
|
|
|
config_space,
|
|
|
irq,
|
|
|
dev_id,
|
|
|
+ device: Arc::new(SpinLock::new(device.clone())),
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+ pub fn pci_device(&self) -> SpinLockGuard<PciDeviceStructureGeneralDevice> {
|
|
|
+ self.device.lock()
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn irq(&self) -> IrqNumber {
|
|
|
+ self.irq
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Transport for PciTransport {
|
|
@@ -446,8 +440,6 @@ pub enum VirtioPciError {
|
|
|
/// `VIRTIO_PCI_CAP_NOTIFY_CFG` capability has a `notify_off_multiplier` that is not a multiple
|
|
|
/// of 2.
|
|
|
InvalidNotifyOffMultiplier(u32),
|
|
|
- /// Unable to find capability such as MSIX or MSI.
|
|
|
- UnableToInitIrq,
|
|
|
/// No valid `VIRTIO_PCI_CAP_ISR_CFG` capability was found.
|
|
|
MissingIsrConfig,
|
|
|
/// An IO BAR was provided rather than a memory BAR.
|
|
@@ -477,7 +469,6 @@ impl Display for VirtioPciError {
|
|
|
"PCI device vender ID {:#06x} was not the VirtIO vendor ID {:#06x}.",
|
|
|
vendor_id, VIRTIO_VENDOR_ID
|
|
|
),
|
|
|
- Self::UnableToInitIrq => write!(f, "Unable to find capability such as MSIX or MSI."),
|
|
|
Self::MissingCommonConfig => write!(
|
|
|
f,
|
|
|
"No valid `VIRTIO_PCI_CAP_COMMON_CFG` capability was found."
|