mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 16:13:27 +00:00
Add virtio legacy interface
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
495c93c2ad
commit
81898362b6
@ -1,6 +1,13 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec, vec::Vec};
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
collections::BTreeMap,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec,
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{fmt::Debug, hint::spin_loop, mem::size_of};
|
||||
|
||||
use aster_block::{
|
||||
@ -8,11 +15,9 @@ use aster_block::{
|
||||
request_queue::{BioRequest, BioRequestSingleQueue},
|
||||
BlockDeviceMeta,
|
||||
};
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use id_alloc::IdAlloc;
|
||||
use log::info;
|
||||
use log::{debug, info};
|
||||
use ostd::{
|
||||
io_mem::IoMem,
|
||||
mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmIo},
|
||||
sync::SpinLock,
|
||||
trap::TrapFrame,
|
||||
@ -26,7 +31,7 @@ use crate::{
|
||||
VirtioDeviceError,
|
||||
},
|
||||
queue::VirtQueue,
|
||||
transport::VirtioTransport,
|
||||
transport::{ConfigManager, VirtioTransport},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -39,8 +44,14 @@ pub struct BlockDevice {
|
||||
impl BlockDevice {
|
||||
/// Creates a new VirtIO-Block driver and registers it.
|
||||
pub(crate) fn init(transport: Box<dyn VirtioTransport>) -> Result<(), VirtioDeviceError> {
|
||||
let is_legacy = transport.is_legacy_version();
|
||||
let device = DeviceInner::init(transport)?;
|
||||
let device_id = device.request_device_id();
|
||||
let device_id = if is_legacy {
|
||||
// FIXME: legacy device do not support `GetId` request.
|
||||
"legacy_blk".to_string()
|
||||
} else {
|
||||
device.request_device_id()
|
||||
};
|
||||
|
||||
let block_device = Arc::new(Self {
|
||||
device,
|
||||
@ -70,9 +81,9 @@ impl BlockDevice {
|
||||
|
||||
/// Negotiate features for the device specified bits 0~23
|
||||
pub(crate) fn negotiate_features(features: u64) -> u64 {
|
||||
let feature = BlockFeatures::from_bits(features).unwrap();
|
||||
let support_features = BlockFeatures::from_bits(features).unwrap();
|
||||
(feature & support_features).bits
|
||||
let mut support_features = BlockFeatures::from_bits_truncate(features);
|
||||
support_features.remove(BlockFeatures::MQ);
|
||||
support_features.bits
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,14 +95,14 @@ impl aster_block::BlockDevice for BlockDevice {
|
||||
fn metadata(&self) -> BlockDeviceMeta {
|
||||
BlockDeviceMeta {
|
||||
max_nr_segments_per_bio: self.queue.max_nr_segments_per_bio(),
|
||||
nr_sectors: VirtioBlockConfig::read_capacity_sectors(&self.device.config).unwrap(),
|
||||
nr_sectors: self.device.config_manager.capacity_sectors(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DeviceInner {
|
||||
config: SafePtr<VirtioBlockConfig, IoMem>,
|
||||
config_manager: ConfigManager<VirtioBlockConfig>,
|
||||
features: VirtioBlockFeature,
|
||||
queue: SpinLock<VirtQueue>,
|
||||
transport: SpinLock<Box<dyn VirtioTransport>>,
|
||||
@ -106,9 +117,10 @@ impl DeviceInner {
|
||||
|
||||
/// Creates and inits the device.
|
||||
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<Arc<Self>, VirtioDeviceError> {
|
||||
let config = VirtioBlockConfig::new(transport.as_mut());
|
||||
let config_manager = VirtioBlockConfig::new_manager(transport.as_ref());
|
||||
debug!("virio_blk_config = {:?}", config_manager.read_config());
|
||||
assert_eq!(
|
||||
VirtioBlockConfig::read_block_size(&config).unwrap(),
|
||||
config_manager.block_size(),
|
||||
VirtioBlockConfig::sector_size(),
|
||||
"currently not support customized device logical block size"
|
||||
);
|
||||
@ -138,7 +150,7 @@ impl DeviceInner {
|
||||
assert!(Self::QUEUE_SIZE as usize * RESP_SIZE <= block_responses.nbytes());
|
||||
|
||||
let device = Arc::new(Self {
|
||||
config,
|
||||
config_manager,
|
||||
features,
|
||||
queue: SpinLock::new(queue),
|
||||
transport: SpinLock::new(transport),
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
pub mod device;
|
||||
|
||||
use core::mem::offset_of;
|
||||
|
||||
use aster_block::SECTOR_SIZE;
|
||||
use aster_util::{field_ptr, safe_ptr::SafePtr};
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use bitflags::bitflags;
|
||||
use int_to_c_enum::TryFromInt;
|
||||
use ostd::{io_mem::IoMem, Pod};
|
||||
use ostd::Pod;
|
||||
|
||||
use crate::transport::VirtioTransport;
|
||||
use crate::transport::{ConfigManager, VirtioTransport};
|
||||
|
||||
pub static DEVICE_NAME: &str = "Virtio-Block";
|
||||
|
||||
@ -73,7 +75,9 @@ pub struct VirtioBlockConfig {
|
||||
topology: VirtioBlockTopology,
|
||||
/// Writeback mode.
|
||||
writeback: u8,
|
||||
unused0: [u8; 3],
|
||||
unused0: u8,
|
||||
/// The number of virtqueues.
|
||||
num_queues: u16,
|
||||
/// The maximum discard sectors for one segment.
|
||||
max_discard_sectors: u32,
|
||||
/// The maximum number of discard segments in a discard command.
|
||||
@ -118,27 +122,78 @@ pub struct VirtioBlockFeature {
|
||||
}
|
||||
|
||||
impl VirtioBlockConfig {
|
||||
pub(self) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||
let memory = transport.device_config_memory();
|
||||
SafePtr::new(memory, 0)
|
||||
pub(self) fn new_manager(transport: &dyn VirtioTransport) -> ConfigManager<Self> {
|
||||
let safe_ptr = transport
|
||||
.device_config_mem()
|
||||
.map(|mem| SafePtr::new(mem, 0));
|
||||
let bar_space = transport.device_config_bar();
|
||||
|
||||
ConfigManager::new(safe_ptr, bar_space)
|
||||
}
|
||||
|
||||
pub(self) const fn sector_size() -> usize {
|
||||
SECTOR_SIZE
|
||||
}
|
||||
}
|
||||
|
||||
pub(self) fn read_block_size(this: &SafePtr<Self, IoMem>) -> ostd::prelude::Result<usize> {
|
||||
field_ptr!(this, Self, blk_size)
|
||||
.read_once()
|
||||
.map(|val| val as usize)
|
||||
impl ConfigManager<VirtioBlockConfig> {
|
||||
pub(super) fn read_config(&self) -> VirtioBlockConfig {
|
||||
let mut blk_config = VirtioBlockConfig::new_uninit();
|
||||
// Only following fields are defined in legacy interface.
|
||||
let cap_low = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, capacity))
|
||||
.unwrap() as u64;
|
||||
let cap_high = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, capacity) + 4)
|
||||
.unwrap() as u64;
|
||||
blk_config.capacity = cap_high << 32 | cap_low;
|
||||
blk_config.size_max = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, size_max))
|
||||
.unwrap();
|
||||
blk_config.seg_max = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, seg_max))
|
||||
.unwrap();
|
||||
blk_config.geometry.cylinders = self
|
||||
.read_once::<u16>(
|
||||
offset_of!(VirtioBlockConfig, geometry)
|
||||
+ offset_of!(VirtioBlockGeometry, cylinders),
|
||||
)
|
||||
.unwrap();
|
||||
blk_config.geometry.heads = self
|
||||
.read_once::<u8>(
|
||||
offset_of!(VirtioBlockConfig, geometry) + offset_of!(VirtioBlockGeometry, heads),
|
||||
)
|
||||
.unwrap();
|
||||
blk_config.geometry.sectors = self
|
||||
.read_once::<u8>(
|
||||
offset_of!(VirtioBlockConfig, geometry) + offset_of!(VirtioBlockGeometry, sectors),
|
||||
)
|
||||
.unwrap();
|
||||
blk_config.blk_size = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, blk_size))
|
||||
.unwrap();
|
||||
|
||||
if self.is_modern() {
|
||||
// TODO: read more field if modern interface exists.
|
||||
}
|
||||
|
||||
blk_config
|
||||
}
|
||||
|
||||
pub(self) fn read_capacity_sectors(
|
||||
this: &SafePtr<Self, IoMem>,
|
||||
) -> ostd::prelude::Result<usize> {
|
||||
field_ptr!(this, Self, capacity)
|
||||
.read_once()
|
||||
.map(|val| val as usize)
|
||||
pub(self) fn block_size(&self) -> usize {
|
||||
self.read_once::<u32>(offset_of!(VirtioBlockConfig, blk_size))
|
||||
.unwrap() as usize
|
||||
}
|
||||
|
||||
pub(self) fn capacity_sectors(&self) -> usize {
|
||||
let cap_low = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, capacity))
|
||||
.unwrap() as usize;
|
||||
let cap_high = self
|
||||
.read_once::<u32>(offset_of!(VirtioBlockConfig, capacity) + 4)
|
||||
.unwrap() as usize;
|
||||
|
||||
cap_high << 32 | cap_low
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use ostd::{io_mem::IoMem, Pod};
|
||||
use core::mem::offset_of;
|
||||
|
||||
use crate::transport::VirtioTransport;
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use ostd::Pod;
|
||||
|
||||
use crate::transport::{ConfigManager, VirtioTransport};
|
||||
|
||||
bitflags::bitflags! {
|
||||
pub struct ConsoleFeatures: u64{
|
||||
@ -22,14 +24,49 @@ bitflags::bitflags! {
|
||||
#[repr(C)]
|
||||
pub struct VirtioConsoleConfig {
|
||||
pub cols: u16,
|
||||
pub row: u16,
|
||||
pub rows: u16,
|
||||
pub max_nr_ports: u32,
|
||||
pub emerg_wr: u32,
|
||||
}
|
||||
|
||||
impl VirtioConsoleConfig {
|
||||
pub(super) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||
let memory = transport.device_config_memory();
|
||||
SafePtr::new(memory, 0)
|
||||
pub(super) fn new_manager(transport: &dyn VirtioTransport) -> ConfigManager<Self> {
|
||||
let safe_ptr = transport
|
||||
.device_config_mem()
|
||||
.map(|mem| SafePtr::new(mem, 0));
|
||||
let bar_space = transport.device_config_bar();
|
||||
ConfigManager::new(safe_ptr, bar_space)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigManager<VirtioConsoleConfig> {
|
||||
pub(super) fn read_config(&self) -> VirtioConsoleConfig {
|
||||
let mut console_config = VirtioConsoleConfig::new_uninit();
|
||||
// Only following fields are defined in legacy interface.
|
||||
console_config.cols = self
|
||||
.read_once::<u16>(offset_of!(VirtioConsoleConfig, cols))
|
||||
.unwrap();
|
||||
console_config.rows = self
|
||||
.read_once::<u16>(offset_of!(VirtioConsoleConfig, rows))
|
||||
.unwrap();
|
||||
console_config.max_nr_ports = self
|
||||
.read_once::<u32>(offset_of!(VirtioConsoleConfig, max_nr_ports))
|
||||
.unwrap();
|
||||
|
||||
console_config
|
||||
}
|
||||
|
||||
/// Performs an emergency write.
|
||||
///
|
||||
/// According to the VirtIO spec 5.3.4:
|
||||
///
|
||||
/// If `VIRTIO_CONSOLE_F_EMERG_WRITE` is supported then the driver can
|
||||
/// use emergency write to output a single character without initializing
|
||||
/// virtio queues, or even acknowledging the feature.
|
||||
pub(super) fn emerg_write(&self, value: u32) {
|
||||
if self.is_modern() {
|
||||
self.write_once(offset_of!(VirtioConsoleConfig, emerg_wr), value)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ use alloc::{boxed::Box, fmt::Debug, string::ToString, sync::Arc, vec::Vec};
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use aster_console::{AnyConsoleDevice, ConsoleCallback};
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use log::debug;
|
||||
use ostd::{
|
||||
io_mem::IoMem,
|
||||
mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmReader},
|
||||
sync::{LocalIrqDisabled, RwLock, SpinLock},
|
||||
trap::TrapFrame,
|
||||
@ -17,11 +15,11 @@ use super::{config::VirtioConsoleConfig, DEVICE_NAME};
|
||||
use crate::{
|
||||
device::{console::config::ConsoleFeatures, VirtioDeviceError},
|
||||
queue::VirtQueue,
|
||||
transport::VirtioTransport,
|
||||
transport::{ConfigManager, VirtioTransport},
|
||||
};
|
||||
|
||||
pub struct ConsoleDevice {
|
||||
config: SafePtr<VirtioConsoleConfig, IoMem>,
|
||||
config_manager: ConfigManager<VirtioConsoleConfig>,
|
||||
transport: SpinLock<Box<dyn VirtioTransport>>,
|
||||
receive_queue: SpinLock<VirtQueue>,
|
||||
transmit_queue: SpinLock<VirtQueue>,
|
||||
@ -61,7 +59,7 @@ impl AnyConsoleDevice for ConsoleDevice {
|
||||
impl Debug for ConsoleDevice {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("ConsoleDevice")
|
||||
.field("config", &self.config)
|
||||
.field("config", &self.config_manager.read_config())
|
||||
.field("transport", &self.transport)
|
||||
.field("receive_queue", &self.receive_queue)
|
||||
.field("transmit_queue", &self.transmit_queue)
|
||||
@ -78,7 +76,9 @@ impl ConsoleDevice {
|
||||
}
|
||||
|
||||
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<(), VirtioDeviceError> {
|
||||
let config = VirtioConsoleConfig::new(transport.as_ref());
|
||||
let config_manager = VirtioConsoleConfig::new_manager(transport.as_ref());
|
||||
debug!("virtio_console_config = {:?}", config_manager.read_config());
|
||||
|
||||
const RECV0_QUEUE_INDEX: u16 = 0;
|
||||
const TRANSMIT0_QUEUE_INDEX: u16 = 1;
|
||||
let receive_queue =
|
||||
@ -97,7 +97,7 @@ impl ConsoleDevice {
|
||||
};
|
||||
|
||||
let device = Arc::new(Self {
|
||||
config,
|
||||
config_manager,
|
||||
transport: SpinLock::new(transport),
|
||||
receive_queue,
|
||||
transmit_queue,
|
||||
|
@ -77,7 +77,7 @@ pub struct VirtioInputConfig {
|
||||
|
||||
impl VirtioInputConfig {
|
||||
pub(self) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||
let memory = transport.device_config_memory();
|
||||
let memory = transport.device_config_mem().unwrap();
|
||||
SafePtr::new(memory, 0)
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use aster_network::EthernetAddr;
|
||||
use aster_util::{field_ptr, safe_ptr::SafePtr};
|
||||
use bitflags::bitflags;
|
||||
use ostd::{io_mem::IoMem, offset_of, Pod};
|
||||
use core::mem::offset_of;
|
||||
|
||||
use crate::transport::VirtioTransport;
|
||||
use aster_network::EthernetAddr;
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use bitflags::bitflags;
|
||||
use ostd::Pod;
|
||||
|
||||
use crate::transport::{ConfigManager, VirtioTransport};
|
||||
|
||||
bitflags! {
|
||||
/// Virtio Net Feature bits.
|
||||
@ -77,38 +79,55 @@ pub struct VirtioNetConfig {
|
||||
}
|
||||
|
||||
impl VirtioNetConfig {
|
||||
pub(super) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||
let memory = transport.device_config_memory();
|
||||
SafePtr::new(memory, 0)
|
||||
}
|
||||
|
||||
pub(super) fn read(this: &SafePtr<Self, IoMem>) -> ostd::prelude::Result<Self> {
|
||||
// TODO: Add a general API to read this byte-by-byte.
|
||||
let mac_data = {
|
||||
let mut mac_data: [u8; 6] = [0; 6];
|
||||
let mut mac_ptr = field_ptr!(this, Self, mac).cast::<u8>();
|
||||
for byte in &mut mac_data {
|
||||
*byte = mac_ptr.read_once().unwrap();
|
||||
mac_ptr.byte_add(1);
|
||||
}
|
||||
mac_data
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
mac: aster_network::EthernetAddr(mac_data),
|
||||
status: field_ptr!(this, Self, status).read_once()?,
|
||||
max_virtqueue_pairs: field_ptr!(this, Self, max_virtqueue_pairs).read_once()?,
|
||||
mtu: field_ptr!(this, Self, mtu).read_once()?,
|
||||
speed: field_ptr!(this, Self, speed).read_once()?,
|
||||
duplex: field_ptr!(this, Self, duplex).read_once()?,
|
||||
rss_max_key_size: field_ptr!(this, Self, rss_max_key_size).read_once()?,
|
||||
rss_max_indirection_table_length: field_ptr!(
|
||||
this,
|
||||
Self,
|
||||
rss_max_indirection_table_length
|
||||
)
|
||||
.read_once()?,
|
||||
supported_hash_types: field_ptr!(this, Self, supported_hash_types).read_once()?,
|
||||
})
|
||||
pub(super) fn new_manager(transport: &dyn VirtioTransport) -> ConfigManager<Self> {
|
||||
let safe_ptr = transport
|
||||
.device_config_mem()
|
||||
.map(|mem| SafePtr::new(mem, 0));
|
||||
let bar_space = transport.device_config_bar();
|
||||
ConfigManager::new(safe_ptr, bar_space)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigManager<VirtioNetConfig> {
|
||||
pub(super) fn read_config(&self) -> VirtioNetConfig {
|
||||
let mut net_config = VirtioNetConfig::new_uninit();
|
||||
// Only following fields are defined in legacy interface.
|
||||
for i in 0..6 {
|
||||
net_config.mac.0[i] = self
|
||||
.read_once::<u8>(offset_of!(VirtioNetConfig, mac) + i)
|
||||
.unwrap();
|
||||
}
|
||||
net_config.status.bits = self
|
||||
.read_once::<u16>(offset_of!(VirtioNetConfig, status))
|
||||
.unwrap();
|
||||
|
||||
if self.is_modern() {
|
||||
net_config.max_virtqueue_pairs = self
|
||||
.read_once::<u16>(offset_of!(VirtioNetConfig, max_virtqueue_pairs))
|
||||
.unwrap();
|
||||
net_config.mtu = self
|
||||
.read_once::<u16>(offset_of!(VirtioNetConfig, mtu))
|
||||
.unwrap();
|
||||
net_config.speed = self
|
||||
.read_once::<u32>(offset_of!(VirtioNetConfig, speed))
|
||||
.unwrap();
|
||||
net_config.duplex = self
|
||||
.read_once::<u8>(offset_of!(VirtioNetConfig, duplex))
|
||||
.unwrap();
|
||||
net_config.rss_max_key_size = self
|
||||
.read_once::<u8>(offset_of!(VirtioNetConfig, rss_max_key_size))
|
||||
.unwrap();
|
||||
net_config.rss_max_indirection_table_length = self
|
||||
.read_once::<u16>(offset_of!(
|
||||
VirtioNetConfig,
|
||||
rss_max_indirection_table_length
|
||||
))
|
||||
.unwrap();
|
||||
net_config.supported_hash_types = self
|
||||
.read_once::<u32>(offset_of!(VirtioNetConfig, supported_hash_types))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
net_config
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ use super::{config::VirtioNetConfig, header::VirtioNetHdr};
|
||||
use crate::{
|
||||
device::{network::config::NetworkFeatures, VirtioDeviceError},
|
||||
queue::{QueueError, VirtQueue},
|
||||
transport::VirtioTransport,
|
||||
transport::{ConfigManager, VirtioTransport},
|
||||
};
|
||||
|
||||
pub struct NetworkDevice {
|
||||
config: VirtioNetConfig,
|
||||
config_manager: ConfigManager<VirtioNetConfig>,
|
||||
// For smoltcp use
|
||||
caps: DeviceCapabilities,
|
||||
mac_addr: EthernetAddr,
|
||||
@ -57,16 +57,15 @@ impl NetworkDevice {
|
||||
}
|
||||
|
||||
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<(), VirtioDeviceError> {
|
||||
let virtio_net_config = VirtioNetConfig::new(transport.as_mut());
|
||||
let config_manager = VirtioNetConfig::new_manager(transport.as_ref());
|
||||
let config = config_manager.read_config();
|
||||
debug!("virtio_net_config = {:?}", config);
|
||||
let mac_addr = config.mac;
|
||||
let features = NetworkFeatures::from_bits_truncate(Self::negotiate_features(
|
||||
transport.read_device_features(),
|
||||
));
|
||||
debug!("virtio_net_config = {:?}", virtio_net_config);
|
||||
debug!("features = {:?}", features);
|
||||
|
||||
let config = VirtioNetConfig::read(&virtio_net_config).unwrap();
|
||||
let mac_addr = config.mac;
|
||||
debug!("mac addr = {:x?}, status = {:?}", mac_addr, config.status);
|
||||
let caps = init_caps(&features, &config);
|
||||
|
||||
let mut send_queue = VirtQueue::new(QUEUE_SEND, QUEUE_SIZE, transport.as_mut())
|
||||
@ -94,7 +93,7 @@ impl NetworkDevice {
|
||||
}
|
||||
|
||||
let mut device = Self {
|
||||
config,
|
||||
config_manager,
|
||||
caps,
|
||||
mac_addr,
|
||||
send_queue,
|
||||
@ -294,7 +293,7 @@ impl AnyNetworkDevice for NetworkDevice {
|
||||
impl Debug for NetworkDevice {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("NetworkDevice")
|
||||
.field("config", &self.config)
|
||||
.field("config", &self.config_manager.read_config())
|
||||
.field("mac_addr", &self.mac_addr)
|
||||
.field("send_queue", &self.send_queue)
|
||||
.field("recv_queue", &self.recv_queue)
|
||||
|
@ -34,7 +34,7 @@ pub struct VirtioVsockConfig {
|
||||
|
||||
impl VirtioVsockConfig {
|
||||
pub(crate) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||
let memory = transport.device_config_memory();
|
||||
let memory = transport.device_config_mem().unwrap();
|
||||
SafePtr::new(memory, 0)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user