mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
fix(driver/virtio): 修改pci transport中断初始化的位置 (#1018)
* fix(driver/virtio): 修改pci transport中断初始化的位置
This commit is contained in:
parent
55e6f0b65f
commit
84c528f53d
@ -163,8 +163,14 @@ unsafe impl Sync for VirtIOBlkDevice {}
|
|||||||
|
|
||||||
impl VirtIOBlkDevice {
|
impl VirtIOBlkDevice {
|
||||||
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
||||||
|
// 设置中断
|
||||||
|
if let Err(err) = transport.setup_irq(dev_id.clone()) {
|
||||||
|
error!("VirtIOBlkDevice '{dev_id:?}' setup_irq failed: {:?}", err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let devname = virtioblk_manager().alloc_id()?;
|
let devname = virtioblk_manager().alloc_id()?;
|
||||||
let irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
|
let irq = Some(transport.irq());
|
||||||
let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
|
let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
|
||||||
if let Err(e) = device_inner {
|
if let Err(e) = device_inner {
|
||||||
error!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e);
|
error!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e);
|
||||||
|
@ -91,6 +91,12 @@ impl Debug for InnerVirtIONetDevice {
|
|||||||
|
|
||||||
impl VirtIONetDevice {
|
impl VirtIONetDevice {
|
||||||
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
||||||
|
// 设置中断
|
||||||
|
if let Err(err) = transport.setup_irq(dev_id.clone()) {
|
||||||
|
error!("VirtIONetDevice '{dev_id:?}' setup_irq failed: {:?}", err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
||||||
match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
||||||
Ok(net) => net,
|
Ok(net) => net,
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
|
use alloc::{string::ToString, sync::Arc};
|
||||||
|
|
||||||
use virtio_drivers::transport::Transport;
|
use virtio_drivers::transport::Transport;
|
||||||
|
|
||||||
use crate::exception::HardwareIrqNumber;
|
use crate::{
|
||||||
|
driver::{
|
||||||
|
base::device::DeviceId,
|
||||||
|
pci::{
|
||||||
|
pci::{PciDeviceStructure, PciError},
|
||||||
|
pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqError, PciIrqMsg, IRQ},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
exception::IrqNumber,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{transport_mmio::VirtIOMmioTransport, transport_pci::PciTransport};
|
use super::{
|
||||||
|
irq::DefaultVirtioIrqHandler, transport_mmio::VirtIOMmioTransport, transport_pci::PciTransport,
|
||||||
|
};
|
||||||
|
|
||||||
pub enum VirtIOTransport {
|
pub enum VirtIOTransport {
|
||||||
Pci(PciTransport),
|
Pci(PciTransport),
|
||||||
@ -10,12 +23,36 @@ pub enum VirtIOTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VirtIOTransport {
|
impl VirtIOTransport {
|
||||||
pub fn irq(&self) -> Option<HardwareIrqNumber> {
|
pub fn irq(&self) -> IrqNumber {
|
||||||
match self {
|
match self {
|
||||||
VirtIOTransport::Mmio(transport) => Some(transport.irq()),
|
VirtIOTransport::Pci(transport) => transport.irq(),
|
||||||
_ => None,
|
VirtIOTransport::Mmio(transport) => IrqNumber::new(transport.irq().data()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 设置中断
|
||||||
|
pub fn setup_irq(&self, dev_id: Arc<DeviceId>) -> Result<(), PciError> {
|
||||||
|
if let VirtIOTransport::Pci(transport) = self {
|
||||||
|
let mut pci_device_guard = transport.pci_device();
|
||||||
|
let standard_device = pci_device_guard.as_standard_device_mut().unwrap();
|
||||||
|
standard_device
|
||||||
|
.irq_init(IRQ::PCI_IRQ_MSIX | IRQ::PCI_IRQ_MSI)
|
||||||
|
.ok_or(PciError::PciIrqError(PciIrqError::IrqNotInited))?;
|
||||||
|
// 中断相关信息
|
||||||
|
let msg = PciIrqMsg {
|
||||||
|
irq_common_message: IrqCommonMsg::init_from(
|
||||||
|
0,
|
||||||
|
"Virtio_IRQ".to_string(),
|
||||||
|
&DefaultVirtioIrqHandler,
|
||||||
|
dev_id,
|
||||||
|
),
|
||||||
|
irq_specific_message: IrqSpecificMsg::msi_default(),
|
||||||
|
};
|
||||||
|
standard_device.irq_install(msg)?;
|
||||||
|
standard_device.irq_enable(true)?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::fmt::Debug for VirtIOTransport {
|
impl core::fmt::Debug for VirtIOTransport {
|
||||||
|
@ -6,17 +6,16 @@ use crate::driver::pci::pci::{
|
|||||||
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
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::driver::pci::root::pci_root_0;
|
||||||
|
|
||||||
use crate::exception::IrqNumber;
|
use crate::exception::IrqNumber;
|
||||||
|
|
||||||
|
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
||||||
use crate::libs::volatile::{
|
use crate::libs::volatile::{
|
||||||
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
||||||
};
|
};
|
||||||
use crate::mm::VirtAddr;
|
use crate::mm::VirtAddr;
|
||||||
|
|
||||||
use alloc::string::ToString;
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
@ -28,7 +27,6 @@ use virtio_drivers::{
|
|||||||
Error, Hal, PhysAddr,
|
Error, Hal, PhysAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::irq::DefaultVirtioIrqHandler;
|
|
||||||
use super::VIRTIO_VENDOR_ID;
|
use super::VIRTIO_VENDOR_ID;
|
||||||
|
|
||||||
/// The offset to add to a VirtIO device ID to get the corresponding PCI device 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]>>,
|
config_space: Option<NonNull<[u32]>>,
|
||||||
irq: IrqNumber,
|
irq: IrqNumber,
|
||||||
dev_id: Arc<DeviceId>,
|
dev_id: Arc<DeviceId>,
|
||||||
|
device: Arc<SpinLock<PciDeviceStructureGeneralDevice>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PciTransport {
|
impl PciTransport {
|
||||||
@ -140,21 +139,7 @@ impl PciTransport {
|
|||||||
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
||||||
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
||||||
irq_vector.push(irq);
|
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空间
|
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
||||||
for capability in device.capabilities().unwrap() {
|
for capability in device.capabilities().unwrap() {
|
||||||
if capability.id != PCI_CAP_ID_VNDR {
|
if capability.id != PCI_CAP_ID_VNDR {
|
||||||
@ -236,8 +221,17 @@ impl PciTransport {
|
|||||||
config_space,
|
config_space,
|
||||||
irq,
|
irq,
|
||||||
dev_id,
|
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 {
|
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
|
/// `VIRTIO_PCI_CAP_NOTIFY_CFG` capability has a `notify_off_multiplier` that is not a multiple
|
||||||
/// of 2.
|
/// of 2.
|
||||||
InvalidNotifyOffMultiplier(u32),
|
InvalidNotifyOffMultiplier(u32),
|
||||||
/// Unable to find capability such as MSIX or MSI.
|
|
||||||
UnableToInitIrq,
|
|
||||||
/// No valid `VIRTIO_PCI_CAP_ISR_CFG` capability was found.
|
/// No valid `VIRTIO_PCI_CAP_ISR_CFG` capability was found.
|
||||||
MissingIsrConfig,
|
MissingIsrConfig,
|
||||||
/// An IO BAR was provided rather than a memory BAR.
|
/// 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}.",
|
"PCI device vender ID {:#06x} was not the VirtIO vendor ID {:#06x}.",
|
||||||
vendor_id, VIRTIO_VENDOR_ID
|
vendor_id, VIRTIO_VENDOR_ID
|
||||||
),
|
),
|
||||||
Self::UnableToInitIrq => write!(f, "Unable to find capability such as MSIX or MSI."),
|
|
||||||
Self::MissingCommonConfig => write!(
|
Self::MissingCommonConfig => write!(
|
||||||
f,
|
f,
|
||||||
"No valid `VIRTIO_PCI_CAP_COMMON_CFG` capability was found."
|
"No valid `VIRTIO_PCI_CAP_COMMON_CFG` capability was found."
|
||||||
|
@ -7,7 +7,11 @@ use crate::{
|
|||||||
driver::net::{NetDevice, Operstate},
|
driver::net::{NetDevice, Operstate},
|
||||||
libs::rwlock::RwLockReadGuard,
|
libs::rwlock::RwLockReadGuard,
|
||||||
net::{socket::SocketPollMethod, NET_DEVICES},
|
net::{socket::SocketPollMethod, NET_DEVICES},
|
||||||
time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
|
time::{
|
||||||
|
sleep::nanosleep,
|
||||||
|
timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
|
||||||
|
PosixTimeSpec,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -118,6 +122,14 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
.remove_default_ipv4_route();
|
.remove_default_ipv4_route();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 在睡眠前释放锁
|
||||||
|
drop(binding);
|
||||||
|
|
||||||
|
let sleep_time = PosixTimeSpec {
|
||||||
|
tv_sec: 5,
|
||||||
|
tv_nsec: 0,
|
||||||
|
};
|
||||||
|
let _ = nanosleep(sleep_time)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(SystemError::ETIMEDOUT);
|
return Err(SystemError::ETIMEDOUT);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user