mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +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 {
|
||||
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 irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
|
||||
let irq = Some(transport.irq());
|
||||
let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
|
||||
if let Err(e) = device_inner {
|
||||
error!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e);
|
||||
|
@ -91,6 +91,12 @@ impl Debug for InnerVirtIONetDevice {
|
||||
|
||||
impl VirtIONetDevice {
|
||||
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> =
|
||||
match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
||||
Ok(net) => net,
|
||||
|
@ -1,8 +1,21 @@
|
||||
use alloc::{string::ToString, sync::Arc};
|
||||
|
||||
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 {
|
||||
Pci(PciTransport),
|
||||
@ -10,12 +23,36 @@ pub enum VirtIOTransport {
|
||||
}
|
||||
|
||||
impl VirtIOTransport {
|
||||
pub fn irq(&self) -> Option<HardwareIrqNumber> {
|
||||
pub fn irq(&self) -> IrqNumber {
|
||||
match self {
|
||||
VirtIOTransport::Mmio(transport) => Some(transport.irq()),
|
||||
_ => None,
|
||||
VirtIOTransport::Pci(transport) => transport.irq(),
|
||||
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 {
|
||||
|
@ -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."
|
||||
|
@ -7,7 +7,11 @@ use crate::{
|
||||
driver::net::{NetDevice, Operstate},
|
||||
libs::rwlock::RwLockReadGuard,
|
||||
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::{
|
||||
@ -118,6 +122,14 @@ fn dhcp_query() -> Result<(), SystemError> {
|
||||
.remove_default_ipv4_route();
|
||||
}
|
||||
}
|
||||
// 在睡眠前释放锁
|
||||
drop(binding);
|
||||
|
||||
let sleep_time = PosixTimeSpec {
|
||||
tv_sec: 5,
|
||||
tv_nsec: 0,
|
||||
};
|
||||
let _ = nanosleep(sleep_time)?;
|
||||
}
|
||||
|
||||
return Err(SystemError::ETIMEDOUT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user