Skip to content

Commit 5162471

Browse files
committed
fix(virtio-net): Only initialize virtqueues after feature negotiation
This refactors the initialization sequence using type state. Signed-off-by: Jens Reidel <[email protected]>
1 parent ea61bb6 commit 5162471

File tree

7 files changed

+125
-122
lines changed

7 files changed

+125
-122
lines changed

src/arch/x86_64/kernel/mmio.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::arch::x86_64::mm::paging;
1313
use crate::arch::x86_64::mm::paging::{
1414
BasePageSize, PageSize, PageTableEntryFlags, PageTableEntryFlagsExt,
1515
};
16-
use crate::drivers::net::virtio::VirtioNetDriver;
16+
use crate::drivers::net::virtio::{Init, VirtioNetDriver};
1717
use crate::drivers::virtio::transport::mmio as mmio_virtio;
1818
use crate::drivers::virtio::transport::mmio::VirtioDriver;
1919
use crate::env;
@@ -28,12 +28,12 @@ const IRQ_NUMBER: u8 = 44 - 32;
2828
static MMIO_DRIVERS: InitCell<Vec<MmioDriver>> = InitCell::new(Vec::new());
2929

3030
pub(crate) enum MmioDriver {
31-
VirtioNet(InterruptTicketMutex<VirtioNetDriver>),
31+
VirtioNet(InterruptTicketMutex<VirtioNetDriver<Init>>),
3232
}
3333

3434
impl MmioDriver {
3535
#[allow(unreachable_patterns)]
36-
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver>> {
36+
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver<Init>>> {
3737
match self {
3838
Self::VirtioNet(drv) => Some(drv),
3939
_ => None,
@@ -186,7 +186,7 @@ pub(crate) fn register_driver(drv: MmioDriver) {
186186
MMIO_DRIVERS.with(|mmio_drivers| mmio_drivers.unwrap().push(drv));
187187
}
188188

189-
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver>> {
189+
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver<Init>>> {
190190
MMIO_DRIVERS
191191
.get()?
192192
.iter()

src/drivers/net/virtio/mmio.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@
22
//!
33
//! The module contains ...
44
5-
use alloc::boxed::Box;
6-
use alloc::vec::Vec;
75
use core::str::FromStr;
86

97
use smoltcp::phy::ChecksumCapabilities;
108
use virtio::mmio::{DeviceRegisters, DeviceRegistersVolatileFieldAccess};
119
use volatile::VolatileRef;
1210

1311
use crate::drivers::InterruptLine;
14-
use crate::drivers::net::virtio::{CtrlQueue, NetDevCfg, RxQueues, TxQueues, VirtioNetDriver};
12+
use crate::drivers::net::virtio::{Init, NetDevCfg, Uninit, VirtioNetDriver};
1513
use crate::drivers::virtio::error::{VirtioError, VirtioNetError};
1614
use crate::drivers::virtio::transport::mmio::{ComCfg, IsrStatus, NotifCfg};
17-
use crate::drivers::virtio::virtqueue::Virtq;
1815

1916
// Backend-dependent interface for Virtio network driver
20-
impl VirtioNetDriver {
17+
impl VirtioNetDriver<Uninit> {
2118
pub fn new(
2219
dev_id: u16,
2320
mut registers: VolatileRef<'static, DeviceRegisters>,
@@ -48,30 +45,19 @@ impl VirtioNetDriver {
4845
1514
4946
};
5047

51-
let send_vqs = TxQueues::new(Vec::<Box<dyn Virtq>>::new(), &dev_cfg);
52-
let recv_vqs = RxQueues::new(Vec::<Box<dyn Virtq>>::new(), &dev_cfg);
5348
Ok(VirtioNetDriver {
5449
dev_cfg,
5550
com_cfg: ComCfg::new(registers, 1),
5651
isr_stat,
5752
notif_cfg,
58-
ctrl_vq: CtrlQueue::new(None),
59-
recv_vqs,
60-
send_vqs,
53+
inner: Uninit,
6154
num_vqs: 0,
6255
mtu,
6356
irq,
6457
checksums: ChecksumCapabilities::default(),
6558
})
6659
}
6760

68-
pub fn print_information(&mut self) {
69-
self.com_cfg.print_information();
70-
if self.dev_status() == virtio::net::S::LINK_UP {
71-
info!("The link of the network device is up!");
72-
}
73-
}
74-
7561
/// Initializes virtio network device by mapping configuration layout to
7662
/// respective structs (configuration structs are:
7763
///
@@ -81,13 +67,13 @@ impl VirtioNetDriver {
8167
dev_id: u16,
8268
registers: VolatileRef<'static, DeviceRegisters>,
8369
irq: InterruptLine,
84-
) -> Result<VirtioNetDriver, VirtioError> {
85-
if let Ok(mut drv) = VirtioNetDriver::new(dev_id, registers, irq) {
70+
) -> Result<VirtioNetDriver<Init>, VirtioError> {
71+
if let Ok(drv) = VirtioNetDriver::new(dev_id, registers, irq) {
8672
match drv.init_dev() {
8773
Err(error_code) => Err(VirtioError::NetDriver(error_code)),
88-
_ => {
89-
drv.print_information();
90-
Ok(drv)
74+
Ok(mut initialized_drv) => {
75+
initialized_drv.print_information();
76+
Ok(initialized_drv)
9177
}
9278
}
9379
} else {
@@ -96,3 +82,12 @@ impl VirtioNetDriver {
9682
}
9783
}
9884
}
85+
86+
impl VirtioNetDriver<Init> {
87+
pub fn print_information(&mut self) {
88+
self.com_cfg.print_information();
89+
if self.dev_status() == virtio::net::S::LINK_UP {
90+
info!("The link of the network device is up!");
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)