diff --git a/kernel/src/arch/x86_64/driver/rtc.rs b/kernel/src/arch/x86_64/driver/rtc.rs index bb6486a11..50a2d9f06 100644 --- a/kernel/src/arch/x86_64/driver/rtc.rs +++ b/kernel/src/arch/x86_64/driver/rtc.rs @@ -163,6 +163,14 @@ impl Device for CmosRtcDevice { fn bus(&self) -> Option> { self.inner().device_common.get_bus_weak_or_clear() } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } } impl KObject for CmosRtcDevice { diff --git a/kernel/src/driver/base/cpu.rs b/kernel/src/driver/base/cpu.rs index cfe344ce3..084867306 100644 --- a/kernel/src/driver/base/cpu.rs +++ b/kernel/src/driver/base/cpu.rs @@ -18,9 +18,9 @@ use super::{ device::{ bus::{subsystem_manager, Bus}, driver::Driver, - Device, DeviceType, IdTable, + Device, DeviceCommonData, DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, subsys::SubSysPrivate, }; @@ -123,23 +123,17 @@ impl CpuSubSystemFakeRootDevice { #[derive(Debug)] struct InnerCpuSubSystemFakeRootDevice { - parent_kobj: Option>, - bus: Option>, - kset: Option>, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, name: String, - kern_inode: Option>, - ktype: Option<&'static dyn KObjType>, } impl InnerCpuSubSystemFakeRootDevice { pub fn new() -> Self { return Self { - parent_kobj: None, - bus: None, - kset: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), name: "".to_string(), - kern_inode: None, - ktype: None, }; } } @@ -154,11 +148,11 @@ impl Device for CpuSubSystemFakeRootDevice { } fn set_bus(&self, bus: Option>) { - self.inner.write().bus = bus; + self.inner.write().device_common.bus = bus; } fn bus(&self) -> Option> { - self.inner.read().bus.clone() + self.inner.read().device_common.bus.clone() } fn driver(&self) -> Option> { @@ -188,6 +182,14 @@ impl Device for CpuSubSystemFakeRootDevice { fn set_class(&self, _class: Option>) { todo!() } + + fn dev_parent(&self) -> Option> { + self.inner.read().device_common.parent.clone() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner.write().device_common.parent = dev_parent; + } } impl KObject for CpuSubSystemFakeRootDevice { @@ -196,35 +198,35 @@ impl KObject for CpuSubSystemFakeRootDevice { } fn set_inode(&self, inode: Option>) { - self.inner.write().kern_inode = inode; + self.inner.write().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.read().kern_inode.clone() + self.inner.read().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.read().parent_kobj.clone() + self.inner.read().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.write().parent_kobj = parent; + self.inner.write().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.read().kset.clone() + self.inner.read().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.write().kset = kset; + self.inner.write().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.read().ktype + self.inner.read().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.write().ktype = ktype; + self.inner.write().kobject_common.kobj_type = ktype; } fn name(&self) -> String { diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index b7e70f893..1ab5f4adc 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -299,9 +299,14 @@ impl BusManager { .ok_or(SystemError::EINVAL)?; debug!("bus '{}' add driver '{}'", bus.name(), driver.name()); - driver.set_kobj_type(Some(&BusDriverKType)); + // driver.set_kobj_type(Some(&BusDriverKType)); let kobj = driver.clone() as Arc; - KObjectManager::add_kobj(kobj, bus.subsystem().drivers_kset())?; + // KObjectManager::add_kobj(kobj, bus.subsystem().drivers_kset())?; + KObjectManager::init_and_add_kobj( + kobj, + bus.subsystem().drivers_kset(), + Some(&BusDriverKType), + )?; bus.subsystem().add_driver_to_vec(driver)?; if bus.subsystem().drivers_autoprobe() { @@ -451,6 +456,7 @@ impl BusManager { } let bus = bus.unwrap(); if bus.subsystem().drivers_autoprobe() { + log::info!("MT bus '{}' autoprobe driver", bus.name()); device_manager().device_initial_probe(dev).ok(); } for interface in bus.subsystem().interfaces() { diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 8803b02b7..0930223bb 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -1,4 +1,5 @@ use alloc::{ + collections::BTreeMap, string::{String, ToString}, sync::{Arc, Weak}, }; @@ -12,16 +13,21 @@ use crate::{ }, exception::irqdata::IrqHandlerData, filesystem::{ + kernfs::KernFSInode, sysfs::{ file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport, }, vfs::syscall::ModeType, }, + libs::{ + rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, + spinlock::{SpinLock, SpinLockGuard}, + }, }; -use core::fmt::Debug; use core::intrinsics::unlikely; +use core::{any::Any, fmt::Debug}; use system_error::SystemError; use self::{ @@ -31,8 +37,10 @@ use self::{ }; use super::{ - class::Class, - kobject::{KObjType, KObject, KObjectManager, KObjectState}, + class::{Class, ClassKObjbectType}, + kobject::{ + KObjType, KObject, KObjectCommonData, KObjectManager, KObjectState, LockedKObjectState, + }, kset::KSet, swnode::software_node_notify, }; @@ -193,6 +201,10 @@ pub trait Device: KObject { fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { None } + + fn dev_parent(&self) -> Option>; + + fn set_dev_parent(&self, parent: Option>); } impl dyn Device { @@ -210,6 +222,7 @@ pub struct DeviceCommonData { pub driver: Option>, pub dead: bool, pub can_match: bool, + pub parent: Option>, } impl Default for DeviceCommonData { @@ -220,6 +233,7 @@ impl Default for DeviceCommonData { driver: None, dead: false, can_match: true, + parent: None, } } } @@ -245,6 +259,13 @@ impl DeviceCommonData { pub fn get_driver_weak_or_clear(&mut self) -> Option> { driver_base_macros::get_weak_or_clear!(self.driver) } + + /// 获取parent字段 + /// + /// 当weak指针的strong count为0的时候,清除弱引用 + pub fn get_parent_weak_or_clear(&mut self) -> Option> { + driver_base_macros::get_weak_or_clear!(self.parent) + } } // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息 @@ -475,21 +496,26 @@ impl DeviceManager { #[allow(dead_code)] pub fn add_device(&self, device: Arc) -> Result<(), SystemError> { // 在这里处理与parent相关的逻辑 - - let current_parent = device - .parent() - .and_then(|x| x.upgrade()) - .and_then(|x| x.arc_any().cast::().ok()); - - let actual_parent = self.get_device_parent(&device, current_parent)?; - if let Some(actual_parent) = actual_parent { + let deivce_parent = device.dev_parent().and_then(|x| x.upgrade()); + if let Some(ref dev) = deivce_parent { + log::info!( + "deivce: {:?} dev parent: {:?}", + device.name().to_string(), + dev.name() + ); + } + let kobject_parent = self.get_device_parent(&device, deivce_parent)?; + if let Some(ref kobj) = kobject_parent { + log::info!("kobject parent: {:?}", kobj.name()); + } + if let Some(kobject_parent) = kobject_parent { // debug!( // "device '{}' parent is '{}', strong_count: {}", // device.name().to_string(), // actual_parent.name(), // Arc::strong_count(&actual_parent) // ); - device.set_parent(Some(Arc::downgrade(&actual_parent))); + device.set_parent(Some(Arc::downgrade(&kobject_parent))); } KObjectManager::add_kobj(device.clone() as Arc, None).map_err(|e| { @@ -536,12 +562,43 @@ impl DeviceManager { return Ok(()); } + /// 用于创建并添加一个新的kset,表示一个设备类目录 + /// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/base/core.c#3159 + fn class_dir_create_and_add( + &self, + class: Arc, + kobject_parent: Arc, + ) -> Arc { + let mut guard = CLASS_DIR_KSET_INSTANCE.write(); + let class_name: String = class.name().to_string(); + let kobject_parent_name = kobject_parent.name(); + let key = format!("{}-{}", class_name, kobject_parent_name); + + // 检查设备类目录是否已经存在 + if let Some(class_dir) = guard.get(&key) { + return class_dir.clone(); + } + + let class_dir: Arc = ClassDir::new(); + + class_dir.set_name(class_name.clone()); + class_dir.set_kobj_type(Some(&ClassKObjbectType)); + class_dir.set_parent(Some(Arc::downgrade(&kobject_parent))); + + KObjectManager::add_kobj(class_dir.clone() as Arc, None) + .expect("add class dir failed"); + + guard.insert(key, class_dir.clone()); + + return class_dir; + } + /// 获取设备真实的parent kobject /// /// ## 参数 /// /// - `device`: 设备 - /// - `current_parent`: 当前的parent kobject + /// - `device_parent`: 父设备 /// /// ## 返回值 /// @@ -551,29 +608,31 @@ impl DeviceManager { fn get_device_parent( &self, device: &Arc, - current_parent: Option>, + device_parent: Option>, ) -> Result>, SystemError> { // debug!("get_device_parent() device:{:?}", device.name()); if device.class().is_some() { - let parent_kobj: Arc; - // debug!("current_parent:{:?}", current_parent); - if let Some(cp) = current_parent { - if cp.class().is_some() { - return Ok(Some(cp.clone() as Arc)); + let kobject_parent: Arc; + if let Some(dp) = device_parent { + if dp.class().is_some() { + return Ok(Some(dp.clone() as Arc)); } else { - parent_kobj = cp.clone() as Arc; + kobject_parent = dp.clone() as Arc; } } else { - parent_kobj = sys_devices_virtual_kset() as Arc; + kobject_parent = sys_devices_virtual_kset() as Arc; } // 是否需要glue dir? - return Ok(Some(parent_kobj)); + let kobject_parent = + self.class_dir_create_and_add(device.class().unwrap(), kobject_parent.clone()); + + return Ok(Some(kobject_parent)); } // subsystems can specify a default root directory for their devices - if current_parent.is_none() { + if device_parent.is_none() { if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { if let Some(root) = bus.root_device().and_then(|x| x.upgrade()) { return Ok(Some(root as Arc)); @@ -581,8 +640,8 @@ impl DeviceManager { } } - if let Some(current_parent) = current_parent { - return Ok(Some(current_parent as Arc)); + if let Some(device_parent) = device_parent { + return Ok(Some(device_parent as Arc)); } return Ok(None); @@ -641,9 +700,8 @@ impl DeviceManager { let subsys_kobj = class.subsystem().subsys() as Arc; sysfs_instance().create_link(Some(&dev_kobj), &subsys_kobj, "subsystem".to_string())?; - // todo: 这里需要处理class的parent逻辑, 添加device链接 - if let Some(parent) = dev.parent().and_then(|x| x.upgrade()) { - let parent_kobj = parent.clone() as Arc; + if let Some(dev_parent) = dev.dev_parent().and_then(|x| x.upgrade()) { + let parent_kobj = dev_parent.clone() as Arc; sysfs_instance() .create_link(Some(&dev_kobj), &parent_kobj, "device".to_string()) .inspect_err(|_e| { @@ -966,3 +1024,93 @@ impl core::hash::Hash for DeviceId { impl Eq for DeviceId {} impl IrqHandlerData for DeviceId {} + +lazy_static! { + /// class_dir列表,通过parent kobject的name和class_dir的name来索引class_dir实例 + static ref CLASS_DIR_KSET_INSTANCE: RwLock>> = RwLock::new(BTreeMap::new()); +} + +#[derive(Debug)] +struct ClassDir { + inner: SpinLock, + locked_kobj_state: LockedKObjectState, +} +#[derive(Debug)] +struct InnerClassDir { + name: Option, + kobject_common: KObjectCommonData, +} + +impl ClassDir { + fn new() -> Arc { + return Arc::new(Self { + inner: SpinLock::new(InnerClassDir { + name: None, + kobject_common: KObjectCommonData::default(), + }), + locked_kobj_state: LockedKObjectState::default(), + }); + } + + fn inner(&self) -> SpinLockGuard { + return self.inner.lock(); + } +} + +impl KObject for ClassDir { + fn as_any_ref(&self) -> &dyn Any { + return self; + } + + fn set_inode(&self, inode: Option>) { + self.inner().kobject_common.kern_inode = inode; + } + + fn inode(&self) -> Option> { + return self.inner().kobject_common.kern_inode.clone(); + } + + fn parent(&self) -> Option> { + return self.inner().kobject_common.parent.clone(); + } + + fn set_parent(&self, parent: Option>) { + self.inner().kobject_common.parent = parent; + } + + fn kset(&self) -> Option> { + return self.inner().kobject_common.kset.clone(); + } + + fn set_kset(&self, kset: Option>) { + self.inner().kobject_common.kset = kset; + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + return self.inner().kobject_common.kobj_type; + } + + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobject_common.kobj_type = ktype; + } + + fn name(&self) -> String { + return self.inner().name.clone().unwrap_or_default(); + } + + fn set_name(&self, name: String) { + self.inner().name = Some(name); + } + + fn kobj_state(&self) -> RwLockReadGuard { + self.locked_kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.locked_kobj_state.write() + } + + fn set_kobj_state(&self, state: KObjectState) { + *self.locked_kobj_state.write() = state; + } +} diff --git a/kernel/src/driver/base/kobject.rs b/kernel/src/driver/base/kobject.rs index 73e3c7eeb..10447b25f 100644 --- a/kernel/src/driver/base/kobject.rs +++ b/kernel/src/driver/base/kobject.rs @@ -178,18 +178,17 @@ impl SysFSOps for KObjectSysFSOps { pub struct KObjectManager; impl KObjectManager { - #[allow(dead_code)] pub fn init_and_add_kobj( kobj: Arc, join_kset: Option>, + kobj_type: Option<&'static dyn KObjType>, ) -> Result<(), SystemError> { - Self::kobj_init(&kobj); + Self::kobj_init(&kobj, kobj_type); Self::add_kobj(kobj, join_kset) } - #[allow(dead_code)] - pub fn kobj_init(kobj: &Arc) { - kobj.set_kobj_type(Some(&DynamicKObjKType)); + pub fn kobj_init(kobj: &Arc, kobj_type: Option<&'static dyn KObjType>) { + kobj.set_kobj_type(kobj_type); } pub fn add_kobj( diff --git a/kernel/src/driver/base/platform/platform_device.rs b/kernel/src/driver/base/platform/platform_device.rs index 32163e009..603c709e8 100644 --- a/kernel/src/driver/base/platform/platform_device.rs +++ b/kernel/src/driver/base/platform/platform_device.rs @@ -11,15 +11,15 @@ use crate::{ bus::{Bus, BusState}, device_manager, driver::Driver, - Device, DevicePrivateData, DeviceType, IdTable, + Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, }, filesystem::kernfs::KernFSInode, libs::{ rwlock::{RwLockReadGuard, RwLockWriteGuard}, - spinlock::SpinLock, + spinlock::{SpinLock, SpinLockGuard}, }, }; use system_error::SystemError; @@ -79,9 +79,9 @@ pub struct PlatformDeviceManager; impl PlatformDeviceManager { /// platform_device_add - add a platform device to device hierarchy pub fn device_add(&self, pdev: Arc) -> Result<(), SystemError> { - if pdev.parent().is_none() { - pdev.set_parent(Some(Arc::downgrade( - &(platform_bus_device() as Arc), + if pdev.dev_parent().is_none() { + pdev.set_dev_parent(Some(Arc::downgrade( + &(platform_bus_device() as Arc), ))); } @@ -136,10 +136,12 @@ impl PlatformBusDevice { data: DevicePrivateData, parent: Option>, ) -> Arc { - return Arc::new(PlatformBusDevice { - inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)), + let platform_bus_device = Self { + inner: SpinLock::new(InnerPlatformBusDevice::new(data)), kobj_state: LockedKObjectState::new(None), - }); + }; + platform_bus_device.set_parent(parent); + return Arc::new(platform_bus_device); } /// @brief: 获取总线的匹配表 @@ -180,38 +182,30 @@ impl PlatformBusDevice { let state = self.inner.lock().state; return state; } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } #[allow(dead_code)] -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct InnerPlatformBusDevice { name: String, data: DevicePrivateData, - state: BusState, // 总线状态 - parent: Option>, // 总线的父对象 - - kernfs_inode: Option>, - /// 当前设备挂载到的总线 - bus: Option>, - /// 当前设备已经匹配的驱动 - driver: Option>, - - ktype: Option<&'static dyn KObjType>, - kset: Option>, + state: BusState, // 总线状态 + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, } impl InnerPlatformBusDevice { - pub fn new(data: DevicePrivateData, parent: Option>) -> Self { + pub fn new(data: DevicePrivateData) -> Self { Self { data, name: "platform".to_string(), state: BusState::NotInitialized, - parent, - kernfs_inode: None, - bus: None, - driver: None, - ktype: None, - kset: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), } } } @@ -222,27 +216,27 @@ impl KObject for PlatformBusDevice { } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn inode(&self) -> Option> { - self.inner.lock().kernfs_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn set_inode(&self, inode: Option>) { - self.inner.lock().kernfs_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().ktype + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().ktype = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn kobj_state(&self) -> RwLockReadGuard { @@ -258,19 +252,19 @@ impl KObject for PlatformBusDevice { } fn name(&self) -> String { - self.inner.lock().name.clone() + self.inner().name.clone() } fn set_name(&self, name: String) { - self.inner.lock().name = name; + self.inner().name = name; } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } } @@ -288,15 +282,15 @@ impl Device for PlatformBusDevice { } fn bus(&self) -> Option> { - self.inner.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.inner.lock().bus = bus; + self.inner().device_common.bus = bus; } fn driver(&self) -> Option> { - self.inner.lock().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } #[inline] @@ -305,7 +299,7 @@ impl Device for PlatformBusDevice { } fn set_driver(&self, driver: Option>) { - self.inner.lock().driver = driver; + self.inner().device_common.driver = driver; } fn can_match(&self) -> bool { @@ -320,7 +314,15 @@ impl Device for PlatformBusDevice { todo!() } - fn set_class(&self, _class: Option>) { - todo!() + fn set_class(&self, class: Option>) { + self.inner().device_common.class = class; + } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; } } diff --git a/kernel/src/driver/base/platform/subsys.rs b/kernel/src/driver/base/platform/subsys.rs index 57e5c2583..b3af5688d 100644 --- a/kernel/src/driver/base/platform/subsys.rs +++ b/kernel/src/driver/base/platform/subsys.rs @@ -5,7 +5,9 @@ use alloc::{ use intertrait::cast::CastArc; use log::error; -use super::{platform_device::PlatformDevice, platform_driver::PlatformDriver}; +use super::{ + platform_bus_device, platform_device::PlatformDevice, platform_driver::PlatformDriver, +}; use crate::{ driver::{ acpi::acpi_manager, @@ -141,6 +143,11 @@ impl Bus for PlatformBus { // 尝试根据设备名称匹配 return Ok(device.name().eq(&driver.name())); } + + fn root_device(&self) -> Option> { + let root_device = platform_bus_device() as Arc; + return Some(Arc::downgrade(&root_device)); + } } #[derive(Debug)] diff --git a/kernel/src/driver/block/virtio_blk.rs b/kernel/src/driver/block/virtio_blk.rs index 73190d17b..136544247 100644 --- a/kernel/src/driver/block/virtio_blk.rs +++ b/kernel/src/driver/block/virtio_blk.rs @@ -1,6 +1,7 @@ use core::{any::Any, fmt::Debug}; use alloc::{ + collections::LinkedList, string::{String, ToString}, sync::{Arc, Weak}, vec::Vec, @@ -32,7 +33,8 @@ use crate::{ sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager}, transport::VirtIOTransport, virtio_impl::HalImpl, - VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID, + VirtIODevice, VirtIODeviceIndex, VirtIODriver, VirtIODriverCommonData, VirtioDeviceId, + VIRTIO_VENDOR_ID, }, }, exception::{irqdesc::IrqReturn, IrqNumber}, @@ -49,6 +51,7 @@ const VIRTIO_BLK_BASENAME: &str = "virtio_blk"; static mut VIRTIO_BLK_DRIVER: Option> = None; #[inline(always)] +#[allow(dead_code)] fn virtio_blk_driver() -> Arc { unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() } } @@ -63,9 +66,16 @@ pub fn virtio_blk_0() -> Option> { .map(|dev| dev.arc_any().downcast().unwrap()) } -pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc) { +pub fn virtio_blk( + transport: VirtIOTransport, + dev_id: Arc, + dev_parent: Option>, +) { let device = VirtIOBlkDevice::new(transport, dev_id); if let Some(device) = device { + if let Some(dev_parent) = dev_parent { + device.set_dev_parent(Some(Arc::downgrade(&dev_parent))); + } virtio_device_manager() .device_add(device.clone() as Arc) .expect("Add virtio blk failed"); @@ -178,10 +188,6 @@ impl VirtIOBlkDevice { }), }); - dev.set_driver(Some(Arc::downgrade( - &(virtio_blk_driver() as Arc), - ))); - Some(dev) } @@ -393,6 +399,14 @@ impl Device for VirtIOBlkDevice { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } } impl KObject for VirtIOBlkDevice { @@ -477,13 +491,22 @@ struct VirtIOBlkDriver { impl VirtIOBlkDriver { pub fn new() -> Arc { let inner = InnerVirtIOBlkDriver { + virtio_driver_common: VirtIODriverCommonData::default(), driver_common: DriverCommonData::default(), kobj_common: KObjectCommonData::default(), }; - Arc::new(VirtIOBlkDriver { + + let id_table = VirtioDeviceId::new( + virtio_drivers::transport::DeviceType::Block as u32, + VIRTIO_VENDOR_ID.into(), + ); + let result = VirtIOBlkDriver { inner: SpinLock::new(inner), kobj_state: LockedKObjectState::default(), - }) + }; + result.add_virtio_id(id_table); + + return Arc::new(result); } fn inner(&self) -> SpinLockGuard { @@ -493,6 +516,7 @@ impl VirtIOBlkDriver { #[derive(Debug)] struct InnerVirtIOBlkDriver { + virtio_driver_common: VirtIODriverCommonData, driver_common: DriverCommonData, kobj_common: KObjectCommonData, } @@ -514,6 +538,14 @@ impl VirtIODriver for VirtIOBlkDriver { block_dev_manager().register(dev as Arc)?; return Ok(()); } + + fn virtio_id_table(&self) -> LinkedList { + self.inner().virtio_driver_common.id_table.clone() + } + + fn add_virtio_id(&self, id: VirtioDeviceId) { + self.inner().virtio_driver_common.id_table.push_back(id); + } } impl Driver for VirtIOBlkDriver { diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index c2278ac66..76bc05b33 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -509,6 +509,14 @@ impl Device for LockedAhciDisk { fn set_class(&self, _class: Option>) { todo!() } + + fn dev_parent(&self) -> Option> { + None + } + + fn set_dev_parent(&self, _dev_parent: Option>) { + todo!() + } } impl BlockDevice for LockedAhciDisk { diff --git a/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs b/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs index 8da1c9fd3..78633ea9e 100644 --- a/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs +++ b/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs @@ -16,9 +16,9 @@ use crate::{ class::Class, device::{ bus::Bus, device_manager, device_number::DeviceNumber, driver::Driver, Device, - DeviceType, IdTable, + DeviceCommonData, DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, }, input::{ @@ -184,13 +184,8 @@ impl Ps2MouseDevice { pub fn new() -> Self { let r = Self { inner: SpinLock::new(InnerPs2MouseDevice { - bus: None, - class: None, - driver: None, - kern_inode: None, - parent: None, - kset: None, - kobj_type: None, + device_common: DeviceCommonData::default(), + kobject_common: KObjectCommonData::default(), current_packet: 0, current_state: MouseState::new(), buf: AllocRingBuffer::new(MOUSE_BUFFER_CAPACITY), @@ -409,17 +404,16 @@ impl Ps2MouseDevice { } Err(SystemError::ETIMEDOUT) } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock_irqsave() + } } #[derive(Debug)] struct InnerPs2MouseDevice { - bus: Option>, - class: Option>, - driver: Option>, - kern_inode: Option>, - parent: Option>, - kset: Option>, - kobj_type: Option<&'static dyn KObjType>, + device_common: DeviceCommonData, + kobject_common: KObjectCommonData, /// 鼠标数据 current_state: MouseState, @@ -446,19 +440,19 @@ impl Device for Ps2MouseDevice { } fn set_bus(&self, bus: Option>) { - self.inner.lock_irqsave().bus = bus; + self.inner().device_common.bus = bus; } fn set_class(&self, class: Option>) { - self.inner.lock_irqsave().class = class; + self.inner().device_common.class = class; } fn driver(&self) -> Option> { - self.inner.lock_irqsave().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } fn set_driver(&self, driver: Option>) { - self.inner.lock_irqsave().driver = driver; + self.inner().device_common.driver = driver; } fn can_match(&self) -> bool { @@ -472,18 +466,26 @@ impl Device for Ps2MouseDevice { } fn bus(&self) -> Option> { - self.inner.lock_irqsave().bus.clone() + self.inner().device_common.bus.clone() } fn class(&self) -> Option> { - let mut guard = self.inner.lock_irqsave(); - let r = guard.class.clone()?.upgrade(); + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); if r.is_none() { - guard.class = None; + guard.device_common.class = None; } return r; } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } impl SerioDevice for Ps2MouseDevice { @@ -530,35 +532,35 @@ impl KObject for Ps2MouseDevice { } fn set_inode(&self, inode: Option>) { - self.inner.lock_irqsave().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock_irqsave().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock_irqsave().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock_irqsave().parent = parent + self.inner().kobject_common.parent = parent } fn kset(&self) -> Option> { - self.inner.lock_irqsave().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock_irqsave().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock_irqsave().kobj_type + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock_irqsave().kobj_type = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> alloc::string::String { @@ -665,12 +667,12 @@ impl IndexNode for Ps2MouseDevice { impl Ps2Device for Ps2MouseDevice {} -pub fn rs_ps2_mouse_device_init(parent: Arc) -> Result<(), SystemError> { +pub fn rs_ps2_mouse_device_init(dev_parent: Arc) -> Result<(), SystemError> { debug!("ps2_mouse_device initializing..."); let psmouse = Arc::new(Ps2MouseDevice::new()); device_manager().device_default_initialize(&(psmouse.clone() as Arc)); - psmouse.set_parent(Some(Arc::downgrade(&parent))); + psmouse.set_dev_parent(Some(Arc::downgrade(&dev_parent))); serio_device_manager().register_port(psmouse.clone() as Arc)?; devfs_register(&psmouse.name(), psmouse.clone()).map_err(|e| { diff --git a/kernel/src/driver/input/serio/i8042/i8042_device.rs b/kernel/src/driver/input/serio/i8042/i8042_device.rs index f774c060d..1e4abc419 100644 --- a/kernel/src/driver/input/serio/i8042/i8042_device.rs +++ b/kernel/src/driver/input/serio/i8042/i8042_device.rs @@ -6,15 +6,17 @@ use alloc::{ use crate::{ driver::base::{ class::Class, - device::{bus::Bus, driver::Driver, Device, DeviceState, DeviceType, IdTable}, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + device::{ + bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceState, DeviceType, IdTable, + }, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, platform::platform_device::PlatformDevice, }, filesystem::kernfs::KernFSInode, libs::{ rwlock::{RwLockReadGuard, RwLockWriteGuard}, - spinlock::SpinLock, + spinlock::{SpinLock, SpinLockGuard}, }, }; @@ -31,13 +33,8 @@ impl I8042PlatformDevice { pub fn new() -> Self { return Self { inner: SpinLock::new(InnerI8042PlatformDevice { - bus: None, - class: None, - driver: None, - kern_inode: None, - parent: None, - kset: None, - kobj_type: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), device_state: DeviceState::NotInitialized, pdev_id: 0, pdev_id_auto: false, @@ -45,17 +42,16 @@ impl I8042PlatformDevice { kobj_state: LockedKObjectState::new(None), }; } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } #[derive(Debug)] pub struct InnerI8042PlatformDevice { - bus: Option>, - class: Option>, - driver: Option>, - kern_inode: Option>, - parent: Option>, - kset: Option>, - kobj_type: Option<&'static dyn KObjType>, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, device_state: DeviceState, pdev_id: i32, pdev_id_auto: bool, @@ -71,31 +67,31 @@ impl Device for I8042PlatformDevice { } fn bus(&self) -> Option> { - self.inner.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.inner.lock().bus = bus; + self.inner().device_common.bus = bus; } fn class(&self) -> Option> { - let mut guard = self.inner.lock(); - let r = guard.class.clone()?.upgrade(); + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); if r.is_none() { - guard.class = None; + guard.device_common.class = None; } return r; } fn set_class(&self, class: Option>) { - self.inner.lock().class = class; + self.inner().device_common.class = class; } fn driver(&self) -> Option> { - self.inner.lock().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } fn set_driver(&self, driver: Option>) { - self.inner.lock().driver = driver; + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { @@ -111,6 +107,14 @@ impl Device for I8042PlatformDevice { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } impl KObject for I8042PlatformDevice { @@ -119,35 +123,35 @@ impl KObject for I8042PlatformDevice { } fn set_inode(&self, inode: Option>) { - self.inner.lock().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().kobj_type + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().kobj_type = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> String { diff --git a/kernel/src/driver/input/serio/i8042/i8042_ports.rs b/kernel/src/driver/input/serio/i8042/i8042_ports.rs index bada7fdfa..f1ed0c6e2 100644 --- a/kernel/src/driver/input/serio/i8042/i8042_ports.rs +++ b/kernel/src/driver/input/serio/i8042/i8042_ports.rs @@ -8,8 +8,8 @@ use crate::{ driver::{ base::{ class::Class, - device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable}, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, }, input::serio::serio_device::SerioDevice, @@ -17,7 +17,7 @@ use crate::{ filesystem::kernfs::KernFSInode, libs::{ rwlock::{RwLockReadGuard, RwLockWriteGuard}, - spinlock::SpinLock, + spinlock::{SpinLock, SpinLockGuard}, }, }; @@ -32,13 +32,8 @@ pub struct I8042AuxPort { #[derive(Debug)] pub struct InnerI8042AuxPort { - bus: Option>, - class: Option>, - driver: Option>, - kern_inode: Option>, - parent: Option>, - kset: Option>, - kobj_type: Option<&'static dyn KObjType>, + device_common: DeviceCommonData, + kobject_common: KObjectCommonData, } impl I8042AuxPort { @@ -46,17 +41,16 @@ impl I8042AuxPort { pub fn new() -> Self { return Self { inner: SpinLock::new(InnerI8042AuxPort { - bus: None, - class: None, - driver: None, - kern_inode: None, - parent: None, - kset: None, - kobj_type: None, + device_common: DeviceCommonData::default(), + kobject_common: KObjectCommonData::default(), }), kobj_state: LockedKObjectState::new(None), }; } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } impl Device for I8042AuxPort { @@ -69,32 +63,32 @@ impl Device for I8042AuxPort { } fn bus(&self) -> Option> { - self.inner.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.inner.lock().bus = bus; + self.inner().device_common.bus = bus; } fn set_class(&self, class: Option>) { - self.inner.lock().class = class; + self.inner().device_common.class = class; } fn class(&self) -> Option> { - let mut guard = self.inner.lock(); - let r = guard.class.clone()?.upgrade(); + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); if r.is_none() { - guard.class = None; + guard.device_common.class = None; } return r; } fn driver(&self) -> Option> { - self.inner.lock().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } fn set_driver(&self, driver: Option>) { - self.inner.lock().driver = driver; + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { @@ -110,6 +104,14 @@ impl Device for I8042AuxPort { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } } impl KObject for I8042AuxPort { @@ -118,35 +120,35 @@ impl KObject for I8042AuxPort { } fn set_inode(&self, inode: Option>) { - self.inner.lock().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().kobj_type + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().kobj_type = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> String { diff --git a/kernel/src/driver/input/serio/i8042/mod.rs b/kernel/src/driver/input/serio/i8042/mod.rs index a65453ac3..b70873ae9 100644 --- a/kernel/src/driver/input/serio/i8042/mod.rs +++ b/kernel/src/driver/input/serio/i8042/mod.rs @@ -6,7 +6,6 @@ use unified_init::macros::unified_init; use crate::{ driver::base::{ device::{device_manager, Device}, - kobject::KObject, platform::{ platform_device::{platform_device_manager, PlatformDevice}, platform_driver::{platform_driver_manager, PlatformDriver}, @@ -65,14 +64,14 @@ pub fn i8042_stop(_serio: &Arc) -> Result<(), SystemError> { /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#i8042_setup_aux pub fn i8042_setup_aux() -> Result<(), SystemError> { let aux_port = Arc::new(I8042AuxPort::new()); - aux_port.set_parent(Some(Arc::downgrade( - &(i8042_platform_device() as Arc), + aux_port.set_dev_parent(Some(Arc::downgrade( + &(i8042_platform_device() as Arc), ))); serio_device_manager().register_port(aux_port.clone() as Arc)?; #[cfg(target_arch = "x86_64")] crate::driver::input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init( - aux_port.clone() as Arc + aux_port.clone() as Arc )?; Ok(()) } diff --git a/kernel/src/driver/net/class.rs b/kernel/src/driver/net/class.rs new file mode 100644 index 000000000..2512c1e9f --- /dev/null +++ b/kernel/src/driver/net/class.rs @@ -0,0 +1,83 @@ +use crate::{ + driver::base::{ + class::{class_manager, Class}, + device::sys_dev_char_kset, + kobject::KObject, + subsys::SubSysPrivate, + }, + filesystem::sysfs::AttributeGroup, + init::initcall::INITCALL_SUBSYS, +}; +use alloc::{ + string::ToString, + sync::{Arc, Weak}, +}; +use system_error::SystemError; +use unified_init::macros::unified_init; + +use super::sysfs::NetAttrGroup; + +/// `/sys/class/net` 的 class 实例 +static mut CLASS_NET_INSTANCE: Option> = None; + +/// 获取 `/sys/class/net` 的 class 实例 +#[inline(always)] +#[allow(dead_code)] +pub fn sys_class_net_instance() -> Option<&'static Arc> { + unsafe { CLASS_NET_INSTANCE.as_ref() } +} + +/// 初始化net子系统 +#[unified_init(INITCALL_SUBSYS)] +pub fn net_init() -> Result<(), SystemError> { + let net_class: Arc = NetClass::new(); + class_manager().class_register(&(net_class.clone() as Arc))?; + + unsafe { + CLASS_NET_INSTANCE = Some(net_class); + } + + return Ok(()); +} + +/// '/sys/class/net' 类 +#[derive(Debug)] +pub struct NetClass { + subsystem: SubSysPrivate, +} + +impl NetClass { + const NAME: &'static str = "net"; + pub fn new() -> Arc { + let net_class = Arc::new(Self { + subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]), + }); + net_class + .subsystem() + .set_class(Some(Arc::downgrade(&net_class) as Weak)); + + return net_class; + } +} + +impl Class for NetClass { + fn name(&self) -> &'static str { + return Self::NAME; + } + + fn dev_kobj(&self) -> Option> { + Some(sys_dev_char_kset() as Arc) + } + + fn set_dev_kobj(&self, _kobj: Arc) { + unimplemented!("NetClass::set_dev_kobj"); + } + + fn subsystem(&self) -> &SubSysPrivate { + return &self.subsystem; + } + + fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { + return &[&NetAttrGroup]; + } +} diff --git a/kernel/src/driver/net/e1000e/e1000e_driver.rs b/kernel/src/driver/net/e1000e/e1000e_driver.rs index fbac2f834..6010ef7ac 100644 --- a/kernel/src/driver/net/e1000e/e1000e_driver.rs +++ b/kernel/src/driver/net/e1000e/e1000e_driver.rs @@ -5,17 +5,20 @@ use crate::{ driver::{ base::{ class::Class, - device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable}, - kobject::{KObjType, KObject, KObjectState}, + device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, }, - net::NetDevice, + net::{register_netdevice, NetDeivceState, NetDevice, NetDeviceCommonData, Operstate}, + }, + libs::{ + rwlock::{RwLockReadGuard, RwLockWriteGuard}, + spinlock::{SpinLock, SpinLockGuard}, }, - libs::spinlock::SpinLock, net::{generate_iface_id, NET_DEVICES}, time::Instant, }; use alloc::{ - string::String, + string::{String, ToString}, sync::{Arc, Weak}, }; use core::{ @@ -32,6 +35,8 @@ use system_error::SystemError; use super::e1000e::{E1000EBuffer, E1000EDevice}; +const DEVICE_NAME: &str = "e1000e"; + pub struct E1000ERxToken(E1000EBuffer); pub struct E1000ETxToken { driver: E1000EDriver, @@ -73,12 +78,24 @@ impl Debug for E1000EDriverWrapper { } } +#[cast_to([sync] NetDevice)] +#[cast_to([sync] Device)] pub struct E1000EInterface { driver: E1000EDriverWrapper, iface_id: usize, iface: SpinLock, name: String, + inner: SpinLock, + locked_kobj_state: LockedKObjectState, } + +#[derive(Debug)] +pub struct InnerE1000EInterface { + netdevice_common: NetDeviceCommonData, + device_common: DeviceCommonData, + kobj_common: KObjectCommonData, +} + impl phy::RxToken for E1000ERxToken { fn consume(mut self, f: F) -> R where @@ -190,10 +207,20 @@ impl E1000EInterface { iface_id, iface: SpinLock::new(iface), name: format!("eth{}", iface_id), + inner: SpinLock::new(InnerE1000EInterface { + netdevice_common: NetDeviceCommonData::default(), + device_common: DeviceCommonData::default(), + kobj_common: KObjectCommonData::default(), + }), + locked_kobj_state: LockedKObjectState::default(), }); return result; } + + pub fn inner(&self) -> SpinLockGuard { + return self.inner.lock(); + } } impl Debug for E1000EInterface { @@ -208,43 +235,70 @@ impl Debug for E1000EInterface { impl Device for E1000EInterface { fn dev_type(&self) -> DeviceType { - todo!() + DeviceType::Net } fn id_table(&self) -> IdTable { - todo!() + IdTable::new(DEVICE_NAME.to_string(), None) + } + + fn bus(&self) -> Option> { + self.inner().device_common.bus.clone() + } + + fn set_bus(&self, bus: Option>) { + self.inner().device_common.bus = bus; } - fn set_bus(&self, _bus: Option>) { - todo!() + fn class(&self) -> Option> { + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); + if r.is_none() { + guard.device_common.class = None; + } + + return r; } - fn set_class(&self, _class: Option>) { - todo!() + fn set_class(&self, class: Option>) { + self.inner().device_common.class = class; } fn driver(&self) -> Option> { - todo!() + let r = self.inner().device_common.driver.clone()?.upgrade(); + if r.is_none() { + self.inner().device_common.driver = None; + } + + return r; } - fn set_driver(&self, _driver: Option>) { - todo!() + fn set_driver(&self, driver: Option>) { + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { - todo!() + false } fn can_match(&self) -> bool { - todo!() + self.inner().device_common.can_match } - fn set_can_match(&self, _can_match: bool) { - todo!() + fn set_can_match(&self, can_match: bool) { + self.inner().device_common.can_match = can_match; } fn state_synced(&self) -> bool { - todo!() + true + } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; } } @@ -260,7 +314,7 @@ impl NetDevice for E1000EInterface { } #[inline] - fn name(&self) -> String { + fn iface_name(&self) -> String { return self.name.clone(); } @@ -295,6 +349,31 @@ impl NetDevice for E1000EInterface { fn inner_iface(&self) -> &SpinLock { return &self.iface; } + + fn addr_assign_type(&self) -> u8 { + return self.inner().netdevice_common.addr_assign_type; + } + + fn net_device_type(&self) -> u16 { + self.inner().netdevice_common.net_device_type = 1; // 以太网设备 + return self.inner().netdevice_common.net_device_type; + } + + fn net_state(&self) -> NetDeivceState { + return self.inner().netdevice_common.state; + } + + fn set_net_state(&self, state: NetDeivceState) { + self.inner().netdevice_common.state |= state; + } + + fn operstate(&self) -> Operstate { + return self.inner().netdevice_common.operstate; + } + + fn set_operstate(&self, state: Operstate) { + self.inner().netdevice_common.operstate = state; + } } impl KObject for E1000EInterface { @@ -302,32 +381,32 @@ impl KObject for E1000EInterface { self } - fn set_inode(&self, _inode: Option>) { - todo!() + fn set_inode(&self, inode: Option>) { + self.inner().kobj_common.kern_inode = inode; } fn inode(&self) -> Option> { - todo!() + self.inner().kobj_common.kern_inode.clone() } fn parent(&self) -> Option> { - todo!() + self.inner().kobj_common.parent.clone() } - fn set_parent(&self, _parent: Option>) { - todo!() + fn set_parent(&self, parent: Option>) { + self.inner().kobj_common.parent = parent; } fn kset(&self) -> Option> { - todo!() + self.inner().kobj_common.kset.clone() } - fn set_kset(&self, _kset: Option>) { - todo!() + fn set_kset(&self, kset: Option>) { + self.inner().kobj_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { - todo!() + self.inner().kobj_common.kobj_type } fn name(&self) -> String { @@ -335,27 +414,23 @@ impl KObject for E1000EInterface { } fn set_name(&self, _name: String) { - todo!() + // do nothing } - fn kobj_state( - &self, - ) -> crate::libs::rwlock::RwLockReadGuard { - todo!() + fn kobj_state(&self) -> RwLockReadGuard { + self.locked_kobj_state.read() } - fn kobj_state_mut( - &self, - ) -> crate::libs::rwlock::RwLockWriteGuard { - todo!() + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.locked_kobj_state.write() } - fn set_kobj_state(&self, _state: KObjectState) { - todo!() + fn set_kobj_state(&self, state: KObjectState) { + *self.locked_kobj_state.write() = state; } - fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { - todo!() + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobj_common.kobj_type = ktype; } } @@ -363,9 +438,14 @@ pub fn e1000e_driver_init(device: E1000EDevice) { let mac = smoltcp::wire::EthernetAddress::from_bytes(&device.mac_address()); let driver = E1000EDriver::new(device); let iface = E1000EInterface::new(driver); + // 标识网络设备已经启动 + iface.set_net_state(NetDeivceState::__LINK_STATE_START); + // 将网卡的接口信息注册到全局的网卡接口信息表中 NET_DEVICES .write_irqsave() .insert(iface.nic_id(), iface.clone()); info!("e1000e driver init successfully!\tMAC: [{}]", mac); + + register_netdevice(iface.clone()).expect("register lo device failed"); } diff --git a/kernel/src/driver/net/loopback.rs b/kernel/src/driver/net/loopback.rs index 32e4f07bb..f8861d43f 100644 --- a/kernel/src/driver/net/loopback.rs +++ b/kernel/src/driver/net/loopback.rs @@ -2,10 +2,15 @@ use crate::arch::rand::rand; use crate::driver::base::class::Class; use crate::driver::base::device::bus::Bus; use crate::driver::base::device::driver::Driver; -use crate::driver::base::device::{Device, DeviceType, IdTable}; -use crate::driver::base::kobject::{KObjType, KObject, KObjectState}; +use crate::driver::base::device::{Device, DeviceCommonData, DeviceType, IdTable}; +use crate::driver::base::kobject::{ + KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState, +}; +use crate::driver::base::kset::KSet; +use crate::filesystem::kernfs::KernFSInode; use crate::init::initcall::INITCALL_DEVICE; -use crate::libs::spinlock::SpinLock; +use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; +use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::net::{generate_iface_id, NET_DEVICES}; use crate::time::Instant; use alloc::collections::VecDeque; @@ -23,7 +28,7 @@ use smoltcp::{ use system_error::SystemError; use unified_init::macros::unified_init; -use super::NetDevice; +use super::{register_netdevice, NetDeivceState, NetDevice, NetDeviceCommonData, Operstate}; const DEVICE_NAME: &str = "loopback"; @@ -235,11 +240,22 @@ impl phy::Device for LoopbackDriver { /// ## LoopbackInterface结构 /// 封装驱动包裹器和iface,设置接口名称 +#[cast_to([sync] NetDevice)] +#[cast_to([sync] Device)] pub struct LoopbackInterface { driver: LoopbackDriverWapper, iface_id: usize, iface: SpinLock, name: String, + inner: SpinLock, + locked_kobj_state: LockedKObjectState, +} + +#[derive(Debug)] +pub struct InnerLoopbackInterface { + netdevice_common: NetDeviceCommonData, + device_common: DeviceCommonData, + kobj_common: KObjectCommonData, } impl LoopbackInterface { @@ -274,8 +290,18 @@ impl LoopbackInterface { iface_id, iface: SpinLock::new(iface), name: "lo".to_string(), + inner: SpinLock::new(InnerLoopbackInterface { + netdevice_common: NetDeviceCommonData::default(), + device_common: DeviceCommonData::default(), + kobj_common: KObjectCommonData::default(), + }), + locked_kobj_state: LockedKObjectState::default(), }) } + + fn inner(&self) -> SpinLockGuard { + return self.inner.lock(); + } } impl Debug for LoopbackInterface { @@ -287,38 +313,38 @@ impl Debug for LoopbackInterface { .finish() } } -//TODO: 向sysfs注册lo设备 + impl KObject for LoopbackInterface { fn as_any_ref(&self) -> &dyn core::any::Any { self } - fn set_inode(&self, _inode: Option>) { - todo!() + fn set_inode(&self, inode: Option>) { + self.inner().kobj_common.kern_inode = inode; } - fn inode(&self) -> Option> { - todo!() + fn inode(&self) -> Option> { + self.inner().kobj_common.kern_inode.clone() } - fn parent(&self) -> Option> { - todo!() + fn parent(&self) -> Option> { + self.inner().kobj_common.parent.clone() } - fn set_parent(&self, _parent: Option>) { - todo!() + fn set_parent(&self, parent: Option>) { + self.inner().kobj_common.parent = parent; } - fn kset(&self) -> Option> { - todo!() + fn kset(&self) -> Option> { + self.inner().kobj_common.kset.clone() } - fn set_kset(&self, _kset: Option>) { - todo!() + fn set_kset(&self, kset: Option>) { + self.inner().kobj_common.kset = kset; } - fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { - todo!() + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + self.inner().kobj_common.kobj_type } fn name(&self) -> String { @@ -326,27 +352,23 @@ impl KObject for LoopbackInterface { } fn set_name(&self, _name: String) { - todo!() + // do nothing } - fn kobj_state( - &self, - ) -> crate::libs::rwlock::RwLockReadGuard { - todo!() + fn kobj_state(&self) -> RwLockReadGuard { + self.locked_kobj_state.read() } - fn kobj_state_mut( - &self, - ) -> crate::libs::rwlock::RwLockWriteGuard { - todo!() + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.locked_kobj_state.write() } - fn set_kobj_state(&self, _state: KObjectState) { - todo!() + fn set_kobj_state(&self, state: KObjectState) { + *self.locked_kobj_state.write() = state; } - fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { - todo!() + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobj_common.kobj_type = ktype; } } @@ -359,43 +381,70 @@ impl Device for LoopbackInterface { IdTable::new(DEVICE_NAME.to_string(), None) } - fn set_bus(&self, _bus: Option>) { - todo!() + fn bus(&self) -> Option> { + self.inner().device_common.bus.clone() } - fn set_class(&self, _class: Option>) { - todo!() + fn set_bus(&self, bus: Option>) { + self.inner().device_common.bus = bus; + } + + fn class(&self) -> Option> { + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); + if r.is_none() { + guard.device_common.class = None; + } + + return r; + } + + fn set_class(&self, class: Option>) { + self.inner().device_common.class = class; } fn driver(&self) -> Option> { - todo!() + let r = self.inner().device_common.driver.clone()?.upgrade(); + if r.is_none() { + self.inner().device_common.driver = None; + } + + return r; } - fn set_driver(&self, _driver: Option>) { - todo!() + fn set_driver(&self, driver: Option>) { + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { - todo!() + false } fn can_match(&self) -> bool { - todo!() + self.inner().device_common.can_match } - fn set_can_match(&self, _can_match: bool) { - todo!() + fn set_can_match(&self, can_match: bool) { + self.inner().device_common.can_match = can_match; } fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } } impl NetDevice for LoopbackInterface { - /// 由于lo网卡设备不是实际的物理设备,其mac地址需要手动设置为一个默认值,这里默认为0200000001 + /// 由于lo网卡设备不是实际的物理设备,其mac地址需要手动设置为一个默认值,这里默认为00:00:00:00:00 fn mac(&self) -> smoltcp::wire::EthernetAddress { - let mac = [0x02, 0x00, 0x00, 0x00, 0x00, 0x01]; + let mac = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; smoltcp::wire::EthernetAddress(mac) } @@ -405,7 +454,7 @@ impl NetDevice for LoopbackInterface { } #[inline] - fn name(&self) -> String { + fn iface_name(&self) -> String { self.name.clone() } /// ## `update_ip_addrs` 用于更新接口的 IP 地址。 @@ -459,6 +508,31 @@ impl NetDevice for LoopbackInterface { fn inner_iface(&self) -> &SpinLock { return &self.iface; } + + fn addr_assign_type(&self) -> u8 { + return self.inner().netdevice_common.addr_assign_type; + } + + fn net_device_type(&self) -> u16 { + self.inner().netdevice_common.net_device_type = 24; // 环回设备 + return self.inner().netdevice_common.net_device_type; + } + + fn net_state(&self) -> NetDeivceState { + return self.inner().netdevice_common.state; + } + + fn set_net_state(&self, state: NetDeivceState) { + self.inner().netdevice_common.state |= state; + } + + fn operstate(&self) -> Operstate { + return self.inner().netdevice_common.operstate; + } + + fn set_operstate(&self, state: Operstate) { + self.inner().netdevice_common.operstate = state; + } } pub fn loopback_probe() { @@ -469,10 +543,14 @@ pub fn loopback_probe() { pub fn loopback_driver_init() { let driver = LoopbackDriver::new(); let iface = LoopbackInterface::new(driver); + // 标识网络设备已经启动 + iface.set_net_state(NetDeivceState::__LINK_STATE_START); NET_DEVICES .write_irqsave() .insert(iface.iface_id, iface.clone()); + + register_netdevice(iface.clone()).expect("register lo device failed"); } /// ## lo网卡设备的注册函数 diff --git a/kernel/src/driver/net/mod.rs b/kernel/src/driver/net/mod.rs index 18e5a3fe1..9a137b0fc 100644 --- a/kernel/src/driver/net/mod.rs +++ b/kernel/src/driver/net/mod.rs @@ -1,24 +1,62 @@ -use alloc::string::String; +use alloc::{string::String, sync::Arc}; use smoltcp::{ iface, wire::{self, EthernetAddress}, }; +use sysfs::netdev_register_kobject; use super::base::device::Device; use crate::libs::spinlock::SpinLock; use system_error::SystemError; +pub mod class; mod dma; pub mod e1000e; pub mod irq_handle; pub mod loopback; +pub mod sysfs; pub mod virtio_net; + +bitflags! { + pub struct NetDeivceState: u16 { + /// 表示网络设备已经启动 + const __LINK_STATE_START = 1 << 0; + /// 表示网络设备在系统中存在,即注册到sysfs中 + const __LINK_STATE_PRESENT = 1 << 1; + /// 表示网络设备没有检测到载波信号 + const __LINK_STATE_NOCARRIER = 1 << 2; + /// 表示设备的链路监视操作处于挂起状态 + const __LINK_STATE_LINKWATCH_PENDING = 1 << 3; + /// 表示设备处于休眠状态 + const __LINK_STATE_DORMANT = 1 << 4; + } +} + +#[derive(Debug, Copy, Clone)] +#[allow(dead_code, non_camel_case_types)] +pub enum Operstate { + /// 网络接口的状态未知 + IF_OPER_UNKNOWN = 0, + /// 网络接口不存在 + IF_OPER_NOTPRESENT = 1, + /// 网络接口已禁用或未连接 + IF_OPER_DOWN = 2, + /// 网络接口的下层接口已关闭 + IF_OPER_LOWERLAYERDOWN = 3, + /// 网络接口正在测试 + IF_OPER_TESTING = 4, + /// 网络接口处于休眠状态 + IF_OPER_DORMANT = 5, + /// 网络接口已启用 + IF_OPER_UP = 6, +} + #[allow(dead_code)] pub trait NetDevice: Device { /// @brief 获取网卡的MAC地址 fn mac(&self) -> EthernetAddress; - fn name(&self) -> String; + fn iface_name(&self) -> String; /// @brief 获取网卡的id fn nic_id(&self) -> usize; @@ -30,4 +68,52 @@ pub trait NetDevice: Device { /// @brief 获取smoltcp的网卡接口类型 fn inner_iface(&self) -> &SpinLock; // fn as_any_ref(&'static self) -> &'static dyn core::any::Any; + + fn addr_assign_type(&self) -> u8; + + fn net_device_type(&self) -> u16; + + fn net_state(&self) -> NetDeivceState; + + fn set_net_state(&self, state: NetDeivceState); + + fn operstate(&self) -> Operstate; + + fn set_operstate(&self, state: Operstate); +} + +/// 网络设备的公共数据 +#[derive(Debug)] +pub struct NetDeviceCommonData { + /// 表示网络接口的地址分配类型 + pub addr_assign_type: u8, + /// 表示网络接口的类型 + pub net_device_type: u16, + /// 表示网络接口的状态 + pub state: NetDeivceState, + /// 表示网络接口的操作状态 + pub operstate: Operstate, +} + +impl Default for NetDeviceCommonData { + fn default() -> Self { + Self { + addr_assign_type: 0, + net_device_type: 1, + state: NetDeivceState::empty(), + operstate: Operstate::IF_OPER_UNKNOWN, + } + } +} + +/// 将网络设备注册到sysfs中 +/// 参考:https://code.dragonos.org.cn/xref/linux-2.6.39/net/core/dev.c?fi=register_netdev#5373 +fn register_netdevice(dev: Arc) -> Result<(), SystemError> { + // 在sysfs中注册设备 + netdev_register_kobject(dev.clone())?; + + // 标识网络设备在系统中存在 + dev.set_net_state(NetDeivceState::__LINK_STATE_PRESENT); + + return Ok(()); } diff --git a/kernel/src/driver/net/sysfs.rs b/kernel/src/driver/net/sysfs.rs new file mode 100644 index 000000000..8878b4a7d --- /dev/null +++ b/kernel/src/driver/net/sysfs.rs @@ -0,0 +1,635 @@ +use crate::{ + driver::base::{ + class::Class, + device::{device_manager, Device}, + kobject::KObject, + }, + filesystem::{ + sysfs::{ + file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO, + SYSFS_ATTR_MODE_RW, + }, + vfs::syscall::ModeType, + }, +}; +use alloc::sync::Arc; +use intertrait::cast::CastArc; +use log::error; +use system_error::SystemError; + +use super::{class::sys_class_net_instance, NetDeivceState, NetDevice, Operstate}; + +/// 将设备注册到`/sys/class/net`目录下 +/// 参考:https://code.dragonos.org.cn/xref/linux-2.6.39/net/core/net-sysfs.c?fi=netdev_register_kobject#1311 +pub fn netdev_register_kobject(dev: Arc) -> Result<(), SystemError> { + // 初始化设备 + device_manager().device_default_initialize(&(dev.clone() as Arc)); + + // 设置dev的class为net + dev.set_class(Some(Arc::downgrade( + &(sys_class_net_instance().cloned().unwrap() as Arc), + ))); + + // 设置设备的kobject名 + dev.set_name(dev.iface_name().clone()); + + device_manager().add_device(dev.clone() as Arc)?; + + return Ok(()); +} + +// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/net/core/net-sysfs.c +#[derive(Debug)] +pub struct NetAttrGroup; + +impl AttributeGroup for NetAttrGroup { + fn name(&self) -> Option<&str> { + None + } + + fn attrs(&self) -> &[&'static dyn Attribute] { + &[ + &AttrAddrAssignType, + &AttrAddrLen, + &AttrDevId, + &AttrIfalias, + &AttrIflink, + &AttrIfindex, + &AttrFeatrues, + &AttrType, + &AttrLinkMode, + &AttrAddress, + &AttrBroadcast, + &AttrCarrier, + &AttrSpeed, + &AttrDuplex, + &AttrDormant, + &AttrOperstate, + &AttrMtu, + &AttrFlags, + &AttrTxQueueLen, + &AttrNetdevGroup, + ] + } + + fn is_visible( + &self, + _kobj: Arc, + attr: &'static dyn Attribute, + ) -> Option { + return Some(attr.mode()); + } +} + +/// # 表示网络接口的MAC地址是如何分配的 +/// - 0(NET_ADDR_PERM): 永久的MAC地址(默认值) +/// - 1(NET_ADDR_RANDOM): 随机生成的MAC地址 +/// - 2(NET_ADDR_STOLEN): 从其他设备中获取的MAC地址 +/// - 3(NET_ADDR_SET): 由用户设置的MAC地址 +#[derive(Debug)] +struct AttrAddrAssignType; + +impl Attribute for AttrAddrAssignType { + fn name(&self) -> &str { + "addr_assign_type" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let net_device = kobj.cast::().map_err(|_| { + error!("AttrAddrAssignType::show() failed: kobj is not a NetDevice"); + SystemError::EINVAL + })?; + let addr_assign_type = net_device.addr_assign_type(); + sysfs_emit_str(buf, &format!("{}\n", addr_assign_type)) + } +} + +/// # 表示网络接口的MAC地址的长度,以字节为单位 +#[derive(Debug)] +struct AttrAddrLen; + +impl Attribute for AttrAddrLen { + fn name(&self) -> &str { + "addr_len" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrAddrLen::show") + } +} + +/// # 表示网络接口的设备ID,是一个十六进制数 +#[derive(Debug)] +struct AttrDevId; + +impl Attribute for AttrDevId { + fn name(&self) -> &str { + "dev_id" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrDevId::show") + } +} + +/// # 表示网络接口的别名,可以设置 +#[derive(Debug)] +struct AttrIfalias; + +impl Attribute for AttrIfalias { + fn name(&self) -> &str { + "ifalias" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RW + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrIfalias::show") + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + todo!("AttrIfalias::store") + } +} + +/// # 表示网络接口的链路索引,用于表示网络接口在系统中的位置 +#[derive(Debug)] +struct AttrIflink; + +impl Attribute for AttrIflink { + fn name(&self) -> &str { + "iflink" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrIflink::show") + } +} + +/// # 标识网络接口的索引 +#[derive(Debug)] +struct AttrIfindex; + +impl Attribute for AttrIfindex { + fn name(&self) -> &str { + "ifindex" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrIfindex::show") + } +} + +/// # 用于显示网络接口支持的特性,这些特性通常由网络驱动程序和硬件能力决定 +#[derive(Debug)] +struct AttrFeatrues; + +impl Attribute for AttrFeatrues { + fn name(&self) -> &str { + "features" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrFeatrues::show") + } +} + +/// # 用于表示网络接口的类型 +/// - 1:ARPHRD_ETHER 以太网接口 +/// - 24:ARPHRD_LOOPBACK 回环接口 +/// - 512:ARPHRD_IEEE80211_RADIOTAP IEEE 802.11 无线接口 +/// - 768:ARPHRD_IEEE802154 IEEE 802.15.4 无线接口 +/// - 769:ARPHRD_6LOWPAN 6LoWPAN接口 +#[derive(Debug)] +struct AttrType; + +impl Attribute for AttrType { + fn name(&self) -> &str { + "type" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let net_deive = kobj.cast::().map_err(|_| { + error!("AttrType::show() failed: kobj is not a NetDevice"); + SystemError::EINVAL + })?; + let net_type = net_deive.net_device_type(); + sysfs_emit_str(buf, &format!("{}\n", net_type)) + } +} + +/// # 表示网络接口的链路模式,用于指示网络接口是否处于自动协商模式 +/// - 0:表示网络接口处于自动协商模式 +/// - 1:表示网络接口处于强制模式,即链路参数(如速度和双工模式)是手动配置的,而不是通过自动协商确定的 +#[derive(Debug)] +struct AttrLinkMode; + +impl Attribute for AttrLinkMode { + fn name(&self) -> &str { + "link_mode" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrLinkMode::show") + } +} + +/// # 表示网络接口的MAC地址 +#[derive(Debug)] +struct AttrAddress; + +impl Attribute for AttrAddress { + fn name(&self) -> &str { + "address" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let net_device = kobj.cast::().map_err(|_| { + error!("AttrAddress::show() failed: kobj is not a NetDevice"); + SystemError::EINVAL + })?; + let mac_addr = net_device.mac(); + sysfs_emit_str(buf, &format!("{}\n", mac_addr)) + } +} + +/// # 表示网络接口的广播地址 +#[derive(Debug)] +struct AttrBroadcast; + +impl Attribute for AttrBroadcast { + fn name(&self) -> &str { + "broadcast" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrBroadcast::show") + } +} + +/// # 表示网络接口的物理链路状态 +/// - 0:表示网络接口处于关闭状态 +/// - 1:表示网络接口处于打开状态 +#[derive(Debug)] +struct AttrCarrier; + +impl Attribute for AttrCarrier { + fn name(&self) -> &str { + "carrier" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let net_device = kobj.cast::().map_err(|_| { + error!("AttrCarrier::show() failed: kobj is not a NetDevice"); + SystemError::EINVAL + })?; + if net_device + .net_state() + .contains(NetDeivceState::__LINK_STATE_START) + && !net_device + .net_state() + .contains(NetDeivceState::__LINK_STATE_NOCARRIER) + { + sysfs_emit_str(buf, "1\n") + } else { + sysfs_emit_str(buf, "0\n") + } + } +} + +/// # 表示网络接口的当前连接速度,单位为Mbps +/// - 特殊值:-1,表示无法确定,通常是因为接口不支持查询速度或接口未连接 +#[derive(Debug)] +struct AttrSpeed; + +impl Attribute for AttrSpeed { + fn name(&self) -> &str { + "speed" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrSpeed::show") + } +} + +/// # 表示网络接口的双工模式 +/// - half:半双工,网络接口不能同时发送和接收数据 +/// - full:全双工,网络接口可以同时发送和接收数据 +/// - unknown:未知,通常表示接口未连接或无法确定双工模式 +#[derive(Debug)] +struct AttrDuplex; + +impl Attribute for AttrDuplex { + fn name(&self) -> &str { + "duplex" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrDuplex::show") + } +} + +/// 表示网络接口是否处于休眠状态 +/// - 0:表示网络接口未处于休眠状态 +/// - 1:表示网络接口处于休眠状态 +#[derive(Debug)] +struct AttrDormant; + +impl Attribute for AttrDormant { + fn name(&self) -> &str { + "dormant" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrDormant::show") + } +} + +/// # 表示网络接口的操作状态 +/// - up:网络接口已启用并且正在运行 +/// - down:网络接口已禁用或未连接 +/// - dormant:网络接口处于休眠状态,等待某些条件满足后激活 +/// - testing:网络接口正在测试中 +/// - unknown:网络接口的状态未知 +/// - notpresent:网络接口硬件不存在 +/// - lowerlayerdown:网络接口的底层设备未启用 +/// - inactive:网络接口未激活 +#[derive(Debug)] +struct AttrOperstate; + +impl Attribute for AttrOperstate { + fn name(&self) -> &str { + "operstate" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + let net_device = _kobj.cast::().map_err(|_| { + error!("AttrOperstate::show() failed: kobj is not a NetDevice"); + SystemError::EINVAL + })?; + if !net_device + .net_state() + .contains(NetDeivceState::__LINK_STATE_START) + { + net_device.set_operstate(Operstate::IF_OPER_DOWN); + } + + let operstate_str = match net_device.operstate() { + Operstate::IF_OPER_UP => "up", + Operstate::IF_OPER_DOWN => "down", + Operstate::IF_OPER_DORMANT => "dormant", + Operstate::IF_OPER_TESTING => "testing", + Operstate::IF_OPER_UNKNOWN => "unknown", + Operstate::IF_OPER_NOTPRESENT => "notpresent", + Operstate::IF_OPER_LOWERLAYERDOWN => "lowerlayerdown", + }; + + sysfs_emit_str(_buf, &format!("{}\n", operstate_str)) + } +} + +/// # 表示网络接口的最大传输单元 +#[derive(Debug)] +struct AttrMtu; + +impl Attribute for AttrMtu { + fn name(&self) -> &str { + "mtu" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrMtu::show") + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + todo!("AttrMtu::store") + } +} + +/// # 表示网络接口的标志,这些标志提供了关于网络接口状态和配置的详细信息 +/// - IFF_UP(0x1):接口已启用 +/// - IFF_BROADCAST(0x2):支持广播 +/// - IFF_DEBUG(0x4):调试模式 +/// - IFF_LOOPBACK(0x8):环回接口 +/// - IFF_POINTOPOINT(0x10):点对点链路 +/// - IFF_NOTRAILERS(0x20):禁用拖尾 +/// - IFF_RUNNING(0x40):资源已分配 +/// - IFF_NOARP(0x80):无ARP协议 +/// - IFF_PROMISC(0x100):混杂模式 +/// - IFF_ALLMULTI(0x200):接收所有多播放数据包 +/// - IFF_ MASTER(0x400):主设备 +/// - IFF_SLAVE(0x800):从设备 +/// - IFF_MULTICAST(0x1000):支持多播 +/// - IFF_PORTSEL(0x2000):可以选择媒体类型 +/// - IFF_AUTOMEDIA(0x4000):自动选择媒体类型 +/// - IFF_DYNAMIC(0x8000):动态接口 +#[derive(Debug)] +struct AttrFlags; + +impl Attribute for AttrFlags { + fn name(&self) -> &str { + "flags" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrFlags::show") + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + todo!("AttrFlags::store") + } +} + +/// # 表示网络接口的传输队列长度 +#[derive(Debug)] +struct AttrTxQueueLen; + +impl Attribute for AttrTxQueueLen { + fn name(&self) -> &str { + "tx_queue_len" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrTxQueueLen::show") + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + todo!("AttrTxQueueLen::store") + } +} + +/// # 表示网络设备所属的设备组 +#[derive(Debug)] +struct AttrNetdevGroup; + +impl Attribute for AttrNetdevGroup { + fn name(&self) -> &str { + "netdev_group" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + todo!("AttrNetdevGroup::show") + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + todo!("AttrNetdevGroup::store") + } +} diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index 58551e4a9..04e524f44 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -6,6 +6,7 @@ use core::{ }; use alloc::{ + collections::LinkedList, string::{String, ToString}, sync::{Arc, Weak}, vec::Vec, @@ -15,7 +16,7 @@ use smoltcp::{iface, phy, wire}; use unified_init::macros::unified_init; use virtio_drivers::device::net::VirtIONet; -use super::NetDevice; +use super::{NetDeivceState, NetDevice, NetDeviceCommonData, Operstate}; use crate::{ arch::rand::rand, driver::{ @@ -29,12 +30,13 @@ use crate::{ kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, }, + net::register_netdevice, virtio::{ - irq::virtio_irq_manager, sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager}, transport::VirtIOTransport, virtio_impl::HalImpl, - VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID, + VirtIODevice, VirtIODeviceIndex, VirtIODriver, VirtIODriverCommonData, VirtioDeviceId, + VIRTIO_VENDOR_ID, }, }, exception::{irqdesc::IrqReturn, IrqNumber}, @@ -51,13 +53,245 @@ use system_error::SystemError; static mut VIRTIO_NET_DRIVER: Option> = None; -const DEVICE_NAME: &str = "virtio_net"; +const VIRTIO_NET_BASENAME: &str = "virtio_net"; #[inline(always)] +#[allow(dead_code)] fn virtio_net_driver() -> Arc { unsafe { VIRTIO_NET_DRIVER.as_ref().unwrap().clone() } } +/// virtio net device +#[derive(Debug)] +#[cast_to([sync] VirtIODevice)] +#[cast_to([sync] Device)] +pub struct VirtIONetDevice { + dev_id: Arc, + inner: SpinLock, + locked_kobj_state: LockedKObjectState, +} + +unsafe impl Send for VirtIONetDevice {} +unsafe impl Sync for VirtIONetDevice {} + +struct InnerVirtIONetDevice { + device_inner: VirtIONicDeviceInner, + name: Option, + virtio_index: Option, + kobj_common: KObjectCommonData, + device_common: DeviceCommonData, +} + +impl Debug for InnerVirtIONetDevice { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("InnerVirtIOBlkDevice").finish() + } +} + +impl VirtIONetDevice { + pub fn new(transport: VirtIOTransport, dev_id: Arc) -> Option> { + let driver_net: VirtIONet = + match VirtIONet::::new(transport, 4096) { + Ok(net) => net, + Err(_) => { + error!("VirtIONet init failed"); + return None; + } + }; + let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address()); + debug!("VirtIONetDevice mac: {:?}", mac); + let device_inner = VirtIONicDeviceInner::new(driver_net); + + let dev = Arc::new(Self { + dev_id, + inner: SpinLock::new(InnerVirtIONetDevice { + device_inner, + name: None, + virtio_index: None, + kobj_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), + }), + locked_kobj_state: LockedKObjectState::default(), + }); + + // dev.set_driver(Some(Arc::downgrade(&virtio_net_driver()) as Weak)); + + return Some(dev); + } + + fn inner(&self) -> SpinLockGuard { + return self.inner.lock(); + } +} + +impl KObject for VirtIONetDevice { + fn as_any_ref(&self) -> &dyn Any { + self + } + + fn set_inode(&self, inode: Option>) { + self.inner().kobj_common.kern_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner().kobj_common.kern_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner().kobj_common.parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner().kobj_common.parent = parent; + } + + fn kset(&self) -> Option> { + self.inner().kobj_common.kset.clone() + } + + fn set_kset(&self, kset: Option>) { + self.inner().kobj_common.kset = kset; + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + self.inner().kobj_common.kobj_type + } + + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobj_common.kobj_type = ktype; + } + + fn name(&self) -> String { + self.device_name() + } + + fn set_name(&self, _name: String) { + // do nothing + } + + fn kobj_state(&self) -> RwLockReadGuard { + self.locked_kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.locked_kobj_state.write() + } + + fn set_kobj_state(&self, state: KObjectState) { + *self.locked_kobj_state.write() = state; + } +} + +impl Device for VirtIONetDevice { + fn dev_type(&self) -> DeviceType { + DeviceType::Net + } + + fn id_table(&self) -> IdTable { + IdTable::new(VIRTIO_NET_BASENAME.to_string(), None) + } + + fn bus(&self) -> Option> { + self.inner().device_common.bus.clone() + } + + fn set_bus(&self, bus: Option>) { + self.inner().device_common.bus = bus; + } + + fn class(&self) -> Option> { + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); + if r.is_none() { + guard.device_common.class = None; + } + + return r; + } + + fn set_class(&self, class: Option>) { + self.inner().device_common.class = class; + } + + fn driver(&self) -> Option> { + let r = self.inner().device_common.driver.clone()?.upgrade(); + if r.is_none() { + self.inner().device_common.driver = None; + } + + return r; + } + + fn set_driver(&self, driver: Option>) { + self.inner().device_common.driver = driver; + } + + fn is_dead(&self) -> bool { + false + } + + fn can_match(&self) -> bool { + self.inner().device_common.can_match + } + + fn set_can_match(&self, can_match: bool) { + self.inner().device_common.can_match = can_match; + } + fn state_synced(&self) -> bool { + true + } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } +} + +impl VirtIODevice for VirtIONetDevice { + fn handle_irq(&self, _irq: IrqNumber) -> Result { + poll_ifaces_try_lock_onetime().ok(); + return Ok(IrqReturn::Handled); + } + + fn dev_id(&self) -> &Arc { + return &self.dev_id; + } + + fn set_device_name(&self, name: String) { + self.inner().name = Some(name); + } + + fn device_name(&self) -> String { + self.inner() + .name + .clone() + .unwrap_or_else(|| "virtio_net".to_string()) + } + + fn set_virtio_device_index(&self, index: VirtIODeviceIndex) { + self.inner().virtio_index = Some(index); + } + + fn virtio_device_index(&self) -> Option { + return self.inner().virtio_index; + } + + fn device_type_id(&self) -> u32 { + virtio_drivers::transport::DeviceType::Network as u32 + } + + fn vendor(&self) -> u32 { + VIRTIO_VENDOR_ID.into() + } + + fn irq(&self) -> Option { + None + } +} + pub struct VirtIoNetImpl { inner: VirtIONet, } @@ -127,13 +361,12 @@ impl Debug for VirtIONicDeviceInner { } } -#[cast_to([sync] VirtIODevice)] +#[cast_to([sync] NetDevice)] #[cast_to([sync] Device)] pub struct VirtioInterface { device_inner: VirtIONicDeviceInnerWrapper, iface_id: usize, iface_name: String, - dev_id: Arc, iface: SpinLock, inner: SpinLock, locked_kobj_state: LockedKObjectState, @@ -141,10 +374,9 @@ pub struct VirtioInterface { #[derive(Debug)] struct InnerVirtIOInterface { - name: Option, - virtio_index: Option, - device_common: DeviceCommonData, kobj_common: KObjectCommonData, + device_common: DeviceCommonData, + netdevice_common: NetDeviceCommonData, } impl core::fmt::Debug for VirtioInterface { @@ -152,7 +384,6 @@ impl core::fmt::Debug for VirtioInterface { f.debug_struct("VirtioInterface") .field("iface_id", &self.iface_id) .field("iface_name", &self.iface_name) - .field("dev_id", &self.dev_id) .field("inner", &self.inner) .field("locked_kobj_state", &self.locked_kobj_state) .finish() @@ -160,7 +391,7 @@ impl core::fmt::Debug for VirtioInterface { } impl VirtioInterface { - pub fn new(mut device_inner: VirtIONicDeviceInner, dev_id: Arc) -> Arc { + pub fn new(mut device_inner: VirtIONicDeviceInner) -> Arc { let iface_id = generate_iface_id(); let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet( wire::EthernetAddress(device_inner.inner.lock().mac_address()), @@ -175,18 +406,13 @@ impl VirtioInterface { locked_kobj_state: LockedKObjectState::default(), iface: SpinLock::new(iface), iface_name: format!("eth{}", iface_id), - dev_id, inner: SpinLock::new(InnerVirtIOInterface { - name: None, - virtio_index: None, - device_common: DeviceCommonData::default(), kobj_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), + netdevice_common: NetDeviceCommonData::default(), }), }); - result.inner().device_common.driver = - Some(Arc::downgrade(&virtio_net_driver()) as Weak); - return result; } @@ -201,47 +427,6 @@ impl VirtioInterface { } } -impl VirtIODevice for VirtioInterface { - fn handle_irq(&self, _irq: IrqNumber) -> Result { - poll_ifaces_try_lock_onetime().ok(); - return Ok(IrqReturn::Handled); - } - - fn irq(&self) -> Option { - None - } - - fn dev_id(&self) -> &Arc { - return &self.dev_id; - } - fn set_virtio_device_index(&self, index: VirtIODeviceIndex) { - self.inner().virtio_index = Some(index); - } - - fn virtio_device_index(&self) -> Option { - return self.inner().virtio_index; - } - - fn set_device_name(&self, name: String) { - self.inner().name = Some(name); - } - - fn device_name(&self) -> String { - self.inner() - .name - .clone() - .unwrap_or_else(|| "virtio_net".to_string()) - } - - fn device_type_id(&self) -> u32 { - virtio_drivers::transport::DeviceType::Network as u32 - } - - fn vendor(&self) -> u32 { - VIRTIO_VENDOR_ID.into() - } -} - impl Drop for VirtioInterface { fn drop(&mut self) { // 从全局的网卡接口信息表中删除这个网卡的接口信息 @@ -255,7 +440,7 @@ impl Device for VirtioInterface { } fn id_table(&self) -> IdTable { - IdTable::new(DEVICE_NAME.to_string(), None) + IdTable::new(VIRTIO_NET_BASENAME.to_string(), None) } fn bus(&self) -> Option> { @@ -308,6 +493,14 @@ impl Device for VirtioInterface { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, parent: Option>) { + self.inner().device_common.parent = parent; + } } impl VirtIONicDeviceInner { @@ -413,22 +606,21 @@ impl phy::RxToken for VirtioNetToken { } /// @brief virtio-net 驱动的初始化与测试 -pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc) { - let driver_net: VirtIONet = - match VirtIONet::::new(transport, 4096) { - Ok(net) => net, - Err(_) => { - error!("VirtIONet init failed"); - return; - } - }; - let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address()); - let dev_inner = VirtIONicDeviceInner::new(driver_net); - let iface = VirtioInterface::new(dev_inner, dev_id); - debug!("To add virtio net: {}, mac: {}", iface.device_name(), mac); - virtio_device_manager() - .device_add(iface.clone() as Arc) - .expect("Add virtio net failed"); +pub fn virtio_net( + transport: VirtIOTransport, + dev_id: Arc, + dev_parent: Option>, +) { + let virtio_net_deivce = VirtIONetDevice::new(transport, dev_id); + if let Some(virtio_net_deivce) = virtio_net_deivce { + debug!("VirtIONetDevice '{:?}' created", virtio_net_deivce.dev_id); + if let Some(dev_parent) = dev_parent { + virtio_net_deivce.set_dev_parent(Some(Arc::downgrade(&dev_parent))); + } + virtio_device_manager() + .device_add(virtio_net_deivce.clone() as Arc) + .expect("Add virtio net failed"); + } } impl NetDevice for VirtioInterface { @@ -443,7 +635,7 @@ impl NetDevice for VirtioInterface { } #[inline] - fn name(&self) -> String { + fn iface_name(&self) -> String { return self.iface_name.clone(); } @@ -485,6 +677,31 @@ impl NetDevice for VirtioInterface { // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { // return self; // } + + fn addr_assign_type(&self) -> u8 { + return self.inner().netdevice_common.addr_assign_type; + } + + fn net_device_type(&self) -> u16 { + self.inner().netdevice_common.net_device_type = 1; // 以太网设备 + return self.inner().netdevice_common.net_device_type; + } + + fn net_state(&self) -> NetDeivceState { + return self.inner().netdevice_common.state; + } + + fn set_net_state(&self, state: NetDeivceState) { + self.inner().netdevice_common.state |= state; + } + + fn operstate(&self) -> Operstate { + return self.inner().netdevice_common.operstate; + } + + fn set_operstate(&self, state: Operstate) { + self.inner().netdevice_common.operstate = state; + } } impl KObject for VirtioInterface { @@ -521,7 +738,7 @@ impl KObject for VirtioInterface { } fn name(&self) -> String { - self.device_name() + self.iface_name.clone() } fn set_name(&self, _name: String) { @@ -569,13 +786,22 @@ struct VirtIONetDriver { impl VirtIONetDriver { pub fn new() -> Arc { let inner = InnerVirtIODriver { + virtio_driver_common: VirtIODriverCommonData::default(), driver_common: DriverCommonData::default(), kobj_common: KObjectCommonData::default(), }; - Arc::new(VirtIONetDriver { + + let id_table = VirtioDeviceId::new( + virtio_drivers::transport::DeviceType::Network as u32, + VIRTIO_VENDOR_ID.into(), + ); + let result = VirtIONetDriver { inner: SpinLock::new(inner), kobj_state: LockedKObjectState::default(), - }) + }; + result.add_virtio_id(id_table); + + return Arc::new(result); } fn inner(&self) -> SpinLockGuard { @@ -585,59 +811,74 @@ impl VirtIONetDriver { #[derive(Debug)] struct InnerVirtIODriver { + virtio_driver_common: VirtIODriverCommonData, driver_common: DriverCommonData, kobj_common: KObjectCommonData, } impl VirtIODriver for VirtIONetDriver { fn probe(&self, device: &Arc) -> Result<(), SystemError> { - let iface = device + log::debug!("VirtIONetDriver::probe()"); + let virtio_net_device = device .clone() .arc_any() - .downcast::() + .downcast::() .map_err(|_| { error!( - "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'", - device.name() - ); + "VirtIONetDriver::probe() failed: device is not a VirtIODevice. Device: '{:?}'", + device.name() + ); SystemError::EINVAL })?; + let iface: Arc = + VirtioInterface::new(virtio_net_device.inner().device_inner.clone()); + // 标识网络设备已经启动 + iface.set_net_state(NetDeivceState::__LINK_STATE_START); + // 设置iface的父设备为virtio_net_device + iface.set_dev_parent(Some(Arc::downgrade(&virtio_net_device) as Weak)); + // 在sysfs中注册iface + register_netdevice(iface.clone() as Arc)?; + // 将网卡的接口信息注册到全局的网卡接口信息表中 NET_DEVICES .write_irqsave() .insert(iface.nic_id(), iface.clone()); - virtio_irq_manager() - .register_device(iface.clone()) - .expect("Register virtio net failed"); - return Ok(()); } + + fn virtio_id_table(&self) -> LinkedList { + self.inner().virtio_driver_common.id_table.clone() + } + + fn add_virtio_id(&self, id: VirtioDeviceId) { + self.inner().virtio_driver_common.id_table.push_back(id); + } } impl Driver for VirtIONetDriver { fn id_table(&self) -> Option { - Some(IdTable::new(DEVICE_NAME.to_string(), None)) + Some(IdTable::new(VIRTIO_NET_BASENAME.to_string(), None)) } fn add_device(&self, device: Arc) { - let iface = device + let virtio_net_device = device .arc_any() - .downcast::() + .downcast::() .expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface"); self.inner() .driver_common .devices - .push(iface as Arc); + .push(virtio_net_device as Arc); } fn delete_device(&self, device: &Arc) { - let _iface = device + let _virtio_net_device = device .clone() .arc_any() - .downcast::() + .downcast::() .expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface"); let mut guard = self.inner(); @@ -702,7 +943,7 @@ impl KObject for VirtIONetDriver { } fn name(&self) -> String { - DEVICE_NAME.to_string() + VIRTIO_NET_BASENAME.to_string() } fn set_name(&self, _name: String) { diff --git a/kernel/src/driver/pci/device.rs b/kernel/src/driver/pci/device.rs index 2d139f52a..e93b25de8 100644 --- a/kernel/src/driver/pci/device.rs +++ b/kernel/src/driver/pci/device.rs @@ -13,7 +13,10 @@ use crate::{ kset::KSet, }, filesystem::kernfs::KernFSInode, - libs::{rwlock::RwLockWriteGuard, spinlock::SpinLock}, + libs::{ + rwlock::RwLockWriteGuard, + spinlock::{SpinLock, SpinLockGuard}, + }, }; use super::{ @@ -41,10 +44,8 @@ impl PciDeviceManager { /// - Err(e) :失败原因 pub fn device_add(&self, pci_dev: Arc) -> Result<(), SystemError> { // pci设备一般放置在/sys/device/pci:xxxx下 - if pci_dev.parent().is_none() { - pci_dev.set_parent(Some(Arc::downgrade( - &(pci_bus_device() as Arc), - ))); + if pci_dev.dev_parent().is_none() { + pci_dev.set_dev_parent(Some(Arc::downgrade(&(pci_bus_device() as Arc)))); } // 设置设备的总线 pci_dev.set_bus(Some(Arc::downgrade(&(pci_bus() as Arc)))); @@ -90,26 +91,34 @@ pub trait PciDevice: Device { #[derive(Debug)] #[cast_to([sync] Device)] pub struct PciBusDevice { - // inner: SpinLock, - device_data: SpinLock, - kobj_data: SpinLock, + inner: SpinLock, kobj_state: LockedKObjectState, name: String, } impl PciBusDevice { pub fn new(parent: Option>) -> Arc { - let common_device = DeviceCommonData::default(); - let common_kobj = KObjectCommonData::default(); let bus_device = Self { - device_data: SpinLock::new(common_device), - kobj_data: SpinLock::new(common_kobj), + inner: SpinLock::new(InnerPciBusDevice { + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), + }), kobj_state: LockedKObjectState::new(None), name: "pci".to_string(), }; bus_device.set_parent(parent); return Arc::new(bus_device); } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } +} + +#[derive(Debug)] +struct InnerPciBusDevice { + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, } impl KObject for PciBusDevice { @@ -118,27 +127,27 @@ impl KObject for PciBusDevice { } fn parent(&self) -> Option> { - self.kobj_data.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn inode(&self) -> Option> { - self.kobj_data.lock().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn set_inode(&self, inode: Option>) { - self.kobj_data.lock().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.kobj_data.lock().kobj_type + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.kobj_data.lock().kobj_type = ktype + self.inner().kobject_common.kobj_type = ktype } fn kset(&self) -> Option> { - self.kobj_data.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn kobj_state( @@ -164,11 +173,11 @@ impl KObject for PciBusDevice { } fn set_kset(&self, kset: Option>) { - self.kobj_data.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn set_parent(&self, parent: Option>) { - self.kobj_data.lock().parent = parent; + self.inner().kobject_common.parent = parent; } } @@ -182,15 +191,15 @@ impl Device for PciBusDevice { } fn bus(&self) -> Option> { - self.device_data.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.device_data.lock().bus = bus + self.inner().device_common.bus = bus } fn driver(&self) -> Option> { - self.device_data.lock().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } fn is_dead(&self) -> bool { @@ -198,7 +207,7 @@ impl Device for PciBusDevice { } fn set_driver(&self, driver: Option>) { - self.device_data.lock().driver = driver; + self.inner().device_common.driver = driver; } fn can_match(&self) -> bool { @@ -216,4 +225,12 @@ impl Device for PciBusDevice { fn state_synced(&self) -> bool { todo!() } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } diff --git a/kernel/src/driver/pci/raw_device.rs b/kernel/src/driver/pci/raw_device.rs index c2be0700e..a93478c03 100644 --- a/kernel/src/driver/pci/raw_device.rs +++ b/kernel/src/driver/pci/raw_device.rs @@ -24,31 +24,36 @@ use super::{ #[cast_to([sync] Device)] #[cast_to([sync] PciDevice)] pub struct PciGeneralDevice { - device_data: RwLock, - kobj_data: RwLock, - name: RwLock>, + inner: RwLock, kobj_state: LockedKObjectState, dev_id: PciDeviceID, header: Arc, } +#[derive(Debug)] +struct InnerPciGeneralDevice { + name: Option, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, +} + impl From<&PciDeviceStructureGeneralDevice> for PciGeneralDevice { fn from(value: &PciDeviceStructureGeneralDevice) -> Self { let value = Arc::new(value.clone()); let name: String = value.common_header.bus_device_function.into(); let kobj_state = LockedKObjectState::new(None); - let common_dev = RwLock::new(DeviceCommonData::default()); - let common_kobj = RwLock::new(KObjectCommonData::default()); let dev_id = PciDeviceID::dummpy(); // dev_id.set_special(PciSpecifiedData::Virtio()); let res = Self { - device_data: common_dev, - kobj_data: common_kobj, + inner: RwLock::new(InnerPciGeneralDevice { + name: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), + }), kobj_state, dev_id, header: value, - name: RwLock::new(None), }; res.set_name(name); res @@ -83,21 +88,21 @@ impl Device for PciGeneralDevice { } fn bus(&self) -> Option> { - self.device_data.read().bus.clone() + self.inner.read().device_common.bus.clone() } fn class(&self) -> Option> { - let mut guard = self.device_data.write(); - let r = guard.class.clone()?.upgrade(); + let mut guard = self.inner.write(); + let r = guard.device_common.class.clone()?.upgrade(); if r.is_none() { - guard.class = None; + guard.device_common.class = None; } return r; } fn driver(&self) -> Option> { - self.device_data.read().driver.clone()?.upgrade() + self.inner.read().device_common.driver.clone()?.upgrade() } fn dev_type(&self) -> DeviceType { @@ -117,22 +122,30 @@ impl Device for PciGeneralDevice { } fn set_bus(&self, bus: Option>) { - self.device_data.write().bus = bus; + self.inner.write().device_common.bus = bus; } fn set_can_match(&self, _can_match: bool) {} fn set_class(&self, class: Option>) { - self.device_data.write().class = class; + self.inner.write().device_common.class = class; } fn set_driver(&self, driver: Option>) { - self.device_data.write().driver = driver + self.inner.write().device_common.driver = driver } fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner.write().device_common.parent.clone() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner.write().device_common.parent = dev_parent; + } } impl KObject for PciGeneralDevice { @@ -141,43 +154,43 @@ impl KObject for PciGeneralDevice { } fn set_inode(&self, inode: Option>) { - self.kobj_data.write().kern_inode = inode; + self.inner.write().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.kobj_data.read().kern_inode.clone() + self.inner.read().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.kobj_data.read().parent.clone() + self.inner.read().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.kobj_data.write().parent = parent; + self.inner.write().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.kobj_data.read().kset.clone() + self.inner.read().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.kobj_data.write().kset = kset; + self.inner.write().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.kobj_data.read().kobj_type + self.inner.read().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.kobj_data.write().kobj_type = ktype; + self.inner.write().kobject_common.kobj_type = ktype; } fn name(&self) -> String { - self.name.read().clone().unwrap() + self.inner.read().name.clone().unwrap() } fn set_name(&self, name: String) { - *self.name.write() = Some(name); + self.inner.write().name = Some(name); } fn kobj_state(&self) -> RwLockReadGuard { diff --git a/kernel/src/driver/pci/subsys.rs b/kernel/src/driver/pci/subsys.rs index c2e5ee393..33851852b 100644 --- a/kernel/src/driver/pci/subsys.rs +++ b/kernel/src/driver/pci/subsys.rs @@ -151,6 +151,11 @@ impl Bus for PciBus { }; return Ok(pci_dev.name().eq(&pci_driver.name())); } + + fn root_device(&self) -> Option> { + let root_device = pci_bus_device() as Arc; + return Some(Arc::downgrade(&root_device)); + } } #[derive(Debug)] diff --git a/kernel/src/driver/pci/test/pt_device.rs b/kernel/src/driver/pci/test/pt_device.rs index 65d1a05b0..8c39d5985 100644 --- a/kernel/src/driver/pci/test/pt_device.rs +++ b/kernel/src/driver/pci/test/pt_device.rs @@ -130,6 +130,14 @@ impl Device for TestDevice { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.device_data.read().parent.clone() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.device_data.write().parent = dev_parent + } } impl KObject for TestDevice { diff --git a/kernel/src/driver/rtc/sysfs.rs b/kernel/src/driver/rtc/sysfs.rs index 63ba3bd51..1384dde2f 100644 --- a/kernel/src/driver/rtc/sysfs.rs +++ b/kernel/src/driver/rtc/sysfs.rs @@ -173,6 +173,14 @@ impl Device for RtcGeneralDevice { fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { Some(&[&RtcAttrGroup]) } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } impl KObject for RtcGeneralDevice { @@ -245,7 +253,7 @@ pub fn rtc_general_device_create( ) -> Arc { let dev = RtcGeneralDevice::new(priority.unwrap_or_default()); device_manager().device_default_initialize(&(dev.clone() as Arc)); - dev.set_parent(Some(Arc::downgrade(real_dev) as Weak)); + dev.set_dev_parent(Some(Arc::downgrade(real_dev) as Weak)); dev.set_class(Some(Arc::downgrade( &(sys_class_rtc_instance().cloned().unwrap() as Arc), ))); diff --git a/kernel/src/driver/serial/serial8250/mod.rs b/kernel/src/driver/serial/serial8250/mod.rs index f12fe63c8..4f9577f86 100644 --- a/kernel/src/driver/serial/serial8250/mod.rs +++ b/kernel/src/driver/serial/serial8250/mod.rs @@ -16,9 +16,9 @@ use crate::{ class::Class, device::{ bus::Bus, device_manager, device_number::DeviceNumber, driver::Driver, Device, - DeviceKObjType, DeviceState, DeviceType, IdTable, + DeviceCommonData, DeviceKObjType, DeviceState, DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, platform::{ platform_device::{platform_device_manager, PlatformDevice}, @@ -212,11 +212,11 @@ impl Device for Serial8250ISADevices { false } fn bus(&self) -> Option> { - self.inner.read().bus.clone() + self.inner.read().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.inner.write().bus = bus; + self.inner.write().device_common.bus = bus; } fn dev_type(&self) -> DeviceType { @@ -228,19 +228,19 @@ impl Device for Serial8250ISADevices { } fn driver(&self) -> Option> { - self.inner.read().driver.clone()?.upgrade() + self.inner.read().device_common.driver.clone()?.upgrade() } fn set_driver(&self, driver: Option>) { - self.inner.write().driver = driver; + self.inner.write().device_common.driver = driver; } fn can_match(&self) -> bool { - self.inner.read().can_match + self.inner.read().device_common.can_match } fn set_can_match(&self, can_match: bool) { - self.inner.write().can_match = can_match; + self.inner.write().device_common.can_match = can_match; } fn state_synced(&self) -> bool { @@ -250,6 +250,14 @@ impl Device for Serial8250ISADevices { fn set_class(&self, _class: Option>) { todo!() } + + fn dev_parent(&self) -> Option> { + self.inner.read().device_common.parent.clone() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner.write().device_common.parent = dev_parent; + } } impl KObject for Serial8250ISADevices { @@ -258,27 +266,27 @@ impl KObject for Serial8250ISADevices { } fn set_inode(&self, inode: Option>) { - self.inner.write().inode = inode; + self.inner.write().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.read().inode.clone() + self.inner.read().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.read().parent_kobj.clone() + self.inner.read().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.write().parent_kobj = parent; + self.inner.write().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.read().kset.clone() + self.inner.read().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.write().kset = kset; + self.inner.write().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { @@ -310,27 +318,17 @@ impl KObject for Serial8250ISADevices { #[derive(Debug)] struct InnerSerial8250ISADevices { - /// 当前设备所述的kset - kset: Option>, - parent_kobj: Option>, - /// 当前设备所述的总线 - bus: Option>, - inode: Option>, - driver: Option>, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, device_state: DeviceState, - can_match: bool, } impl InnerSerial8250ISADevices { fn new() -> Self { Self { - kset: None, - parent_kobj: None, - bus: None, - inode: None, - driver: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), device_state: DeviceState::NotInitialized, - can_match: false, } } } diff --git a/kernel/src/driver/tty/tty_device.rs b/kernel/src/driver/tty/tty_device.rs index 56a053b40..61f408164 100644 --- a/kernel/src/driver/tty/tty_device.rs +++ b/kernel/src/driver/tty/tty_device.rs @@ -549,6 +549,17 @@ impl Device for TtyDevice { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + None + } + + fn set_dev_parent( + &self, + _dev_parent: Option>, + ) { + todo!() + } } impl CharDevice for TtyDevice { diff --git a/kernel/src/driver/video/fbdev/base/fbcon/mod.rs b/kernel/src/driver/video/fbdev/base/fbcon/mod.rs index ac6e50cfb..3a5c6f9c6 100644 --- a/kernel/src/driver/video/fbdev/base/fbcon/mod.rs +++ b/kernel/src/driver/video/fbdev/base/fbcon/mod.rs @@ -10,8 +10,11 @@ use crate::{ driver::{ base::{ class::Class, - device::{bus::Bus, device_manager, driver::Driver, Device, DeviceType, IdTable}, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + device::{ + bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, + IdTable, + }, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, }, tty::virtual_terminal::virtual_console::{CursorOperation, VcCursor, VirtualConsoleData}, @@ -89,12 +92,8 @@ struct InnerFbConsoleManager {} #[derive(Debug)] struct InnerFbConsoleDevice { - kernfs_inode: Option>, - parent: Option>, - kset: Option>, - bus: Option>, - driver: Option>, - ktype: Option<&'static dyn KObjType>, + device_common: DeviceCommonData, + kobject_common: KObjectCommonData, } /// `/sys/class/graphics/fbcon`代表的 framebuffer console 设备 @@ -111,16 +110,16 @@ impl FbConsoleDevice { pub fn new() -> Arc { return Arc::new(Self { inner: SpinLock::new(InnerFbConsoleDevice { - kernfs_inode: None, - parent: None, - kset: None, - bus: None, - ktype: None, - driver: None, + device_common: DeviceCommonData::default(), + kobject_common: KObjectCommonData::default(), }), kobj_state: LockedKObjectState::new(None), }); } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } impl KObject for FbConsoleDevice { @@ -129,35 +128,35 @@ impl KObject for FbConsoleDevice { } fn set_inode(&self, inode: Option>) { - self.inner.lock().kernfs_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock().kernfs_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().ktype + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().ktype = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> String { @@ -191,11 +190,11 @@ impl Device for FbConsoleDevice { } fn set_bus(&self, bus: Option>) { - self.inner.lock().bus = bus; + self.inner().device_common.bus = bus; } fn bus(&self) -> Option> { - self.inner.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_class(&self, _class: Option>) { @@ -208,27 +207,27 @@ impl Device for FbConsoleDevice { } fn driver(&self) -> Option> { - self.inner - .lock() + self.inner() + .device_common .driver .clone() .and_then(|driver| driver.upgrade()) } fn set_driver(&self, driver: Option>) { - self.inner.lock().driver = driver; + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { - todo!() + self.inner().device_common.dead } fn can_match(&self) -> bool { - todo!() + self.inner().device_common.can_match } - fn set_can_match(&self, _can_match: bool) { - todo!() + fn set_can_match(&self, can_match: bool) { + self.inner().device_common.can_match = can_match; } fn state_synced(&self) -> bool { @@ -238,6 +237,14 @@ impl Device for FbConsoleDevice { fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { return Some(&[&AnonymousAttributeGroup]); } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } /// framebuffer console设备的匿名属性组 diff --git a/kernel/src/driver/video/fbdev/base/fbmem.rs b/kernel/src/driver/video/fbdev/base/fbmem.rs index 8031fc6d3..bcea81ac8 100644 --- a/kernel/src/driver/video/fbdev/base/fbmem.rs +++ b/kernel/src/driver/video/fbdev/base/fbmem.rs @@ -18,9 +18,9 @@ use crate::{ device_manager, device_number::{DeviceNumber, Major}, driver::Driver, - sys_dev_char_kset, Device, DeviceType, IdTable, + sys_dev_char_kset, Device, DeviceCommonData, DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, subsys::SubSysPrivate, }, @@ -146,7 +146,7 @@ impl FrameBufferManager { fb.set_fb_id(id); let fb_device = FbDevice::new(Arc::downgrade(&fb) as Weak, id); device_manager().device_default_initialize(&(fb_device.clone() as Arc)); - fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc)))); + fb_device.set_dev_parent(Some(Arc::downgrade(&(fb.clone() as Arc)))); fb.set_fb_device(Some(fb_device.clone())); @@ -218,10 +218,8 @@ impl FbDevice { let r = Arc::new(Self { inner: SpinLock::new(InnerFbDevice { fb, - kern_inode: None, - parent: None, - kset: None, - ktype: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), fb_id: id, device_inode_fs: None, devfs_metadata: Metadata::new( @@ -253,15 +251,17 @@ impl FbDevice { fn do_device_number(&self, inner_guard: &SpinLockGuard<'_, InnerFbDevice>) -> DeviceNumber { DeviceNumber::new(Major::FB_MAJOR, inner_guard.fb_id.data()) } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } #[derive(Debug)] struct InnerFbDevice { fb: Weak, - kern_inode: Option>, - parent: Option>, - kset: Option>, - ktype: Option<&'static dyn KObjType>, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, /// 帧缓冲区id fb_id: FbId, @@ -276,35 +276,35 @@ impl KObject for FbDevice { } fn set_inode(&self, inode: Option>) { - self.inner.lock().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().ktype + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().ktype = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> String { @@ -375,6 +375,14 @@ impl Device for FbDevice { fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { Some(&[&FbDeviceAttrGroup]) } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } impl DeviceINode for FbDevice { diff --git a/kernel/src/driver/video/fbdev/vesafb.rs b/kernel/src/driver/video/fbdev/vesafb.rs index 0c58c161a..2a267dee2 100644 --- a/kernel/src/driver/video/fbdev/vesafb.rs +++ b/kernel/src/driver/video/fbdev/vesafb.rs @@ -14,9 +14,10 @@ use crate::{ base::{ class::Class, device::{ - bus::Bus, device_manager, driver::Driver, Device, DeviceState, DeviceType, IdTable, + bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceState, + DeviceType, IdTable, }, - kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, kset::KSet, platform::{ platform_device::{platform_device_manager, PlatformDevice}, @@ -35,7 +36,7 @@ use crate::{ libs::{ once::Once, rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, - spinlock::SpinLock, + spinlock::{SpinLock, SpinLockGuard}, }, mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr}, }; @@ -86,13 +87,8 @@ impl VesaFb { fb_info_data.pesudo_palette.resize(256, 0); return Self { inner: SpinLock::new(InnerVesaFb { - bus: None, - class: None, - driver: None, - kern_inode: None, - parent: None, - kset: None, - kobj_type: None, + kobject_common: KObjectCommonData::default(), + device_common: DeviceCommonData::default(), device_state: DeviceState::NotInitialized, pdev_id: 0, pdev_id_auto: false, @@ -104,17 +100,16 @@ impl VesaFb { fb_data: RwLock::new(fb_info_data), }; } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } } #[derive(Debug)] struct InnerVesaFb { - bus: Option>, - class: Option>, - driver: Option>, - kern_inode: Option>, - parent: Option>, - kset: Option>, - kobj_type: Option<&'static dyn KObjType>, + kobject_common: KObjectCommonData, + device_common: DeviceCommonData, device_state: DeviceState, pdev_id: i32, pdev_id_auto: bool, @@ -165,35 +160,35 @@ impl Device for VesaFb { } fn bus(&self) -> Option> { - self.inner.lock().bus.clone() + self.inner().device_common.bus.clone() } fn set_bus(&self, bus: Option>) { - self.inner.lock().bus = bus; + self.inner().device_common.bus = bus; } fn set_class(&self, class: Option>) { - self.inner.lock().class = class; + self.inner().device_common.class = class; } fn class(&self) -> Option> { - let mut guard = self.inner.lock(); + let mut guard = self.inner(); - let r = guard.class.clone()?.upgrade(); + let r = guard.device_common.class.clone()?.upgrade(); if r.is_none() { // 为了让弱引用失效 - guard.class = None; + guard.device_common.class = None; } return r; } fn driver(&self) -> Option> { - self.inner.lock().driver.clone()?.upgrade() + self.inner().device_common.driver.clone()?.upgrade() } fn set_driver(&self, driver: Option>) { - self.inner.lock().driver = driver; + self.inner().device_common.driver = driver; } fn is_dead(&self) -> bool { @@ -209,6 +204,14 @@ impl Device for VesaFb { fn state_synced(&self) -> bool { true } + + fn dev_parent(&self) -> Option> { + self.inner().device_common.get_parent_weak_or_clear() + } + + fn set_dev_parent(&self, dev_parent: Option>) { + self.inner().device_common.parent = dev_parent; + } } impl KObject for VesaFb { @@ -217,35 +220,35 @@ impl KObject for VesaFb { } fn set_inode(&self, inode: Option>) { - self.inner.lock().kern_inode = inode; + self.inner().kobject_common.kern_inode = inode; } fn inode(&self) -> Option> { - self.inner.lock().kern_inode.clone() + self.inner().kobject_common.kern_inode.clone() } fn parent(&self) -> Option> { - self.inner.lock().parent.clone() + self.inner().kobject_common.parent.clone() } fn set_parent(&self, parent: Option>) { - self.inner.lock().parent = parent; + self.inner().kobject_common.parent = parent; } fn kset(&self) -> Option> { - self.inner.lock().kset.clone() + self.inner().kobject_common.kset.clone() } fn set_kset(&self, kset: Option>) { - self.inner.lock().kset = kset; + self.inner().kobject_common.kset = kset; } fn kobj_type(&self) -> Option<&'static dyn KObjType> { - self.inner.lock().kobj_type + self.inner().kobject_common.kobj_type } fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { - self.inner.lock().kobj_type = ktype; + self.inner().kobject_common.kobj_type = ktype; } fn name(&self) -> String { diff --git a/kernel/src/driver/virtio/mmio.rs b/kernel/src/driver/virtio/mmio.rs index 815cce58d..f33ade3f6 100644 --- a/kernel/src/driver/virtio/mmio.rs +++ b/kernel/src/driver/virtio/mmio.rs @@ -20,7 +20,7 @@ fn do_probe_virtio_mmio() -> Result<(), SystemError> { let do_check = |node: FdtNode| -> Result<(), SystemError> { let mmio_transport = VirtIOMmioTransport::new(node)?; let device_id = mmio_transport.device_id(); - virtio_device_init(VirtIOTransport::Mmio(mmio_transport), device_id); + virtio_device_init(VirtIOTransport::Mmio(mmio_transport), device_id, None); Ok(()) }; diff --git a/kernel/src/driver/virtio/mod.rs b/kernel/src/driver/virtio/mod.rs index 024d44074..d0a1db91c 100644 --- a/kernel/src/driver/virtio/mod.rs +++ b/kernel/src/driver/virtio/mod.rs @@ -1,4 +1,4 @@ -use alloc::{string::String, sync::Arc}; +use alloc::{collections::LinkedList, string::String, sync::Arc}; use system_error::SystemError; use crate::exception::{irqdesc::IrqReturn, IrqNumber}; @@ -17,6 +17,8 @@ pub mod virtio_impl; /// virtio 设备厂商ID pub const VIRTIO_VENDOR_ID: u16 = 0x1af4; +// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/include/linux/mod_devicetable.h?fi=VIRTIO_DEV_ANY_ID#453 +pub const VIRTIO_DEV_ANY_ID: u32 = 0xffffffff; #[allow(dead_code)] pub trait VirtIODevice: Device { @@ -48,6 +50,28 @@ pub trait VirtIODevice: Device { pub trait VirtIODriver: Driver { fn probe(&self, device: &Arc) -> Result<(), SystemError>; + + fn virtio_id_table(&self) -> LinkedList; + + fn add_virtio_id(&self, id: VirtioDeviceId); } int_like!(VirtIODeviceIndex, usize); + +#[derive(Debug, Default)] +pub struct VirtIODriverCommonData { + pub id_table: LinkedList, +} + +/// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/include/linux/mod_devicetable.h#449 +#[derive(Debug, Default, Clone)] +pub struct VirtioDeviceId { + pub device: u32, + pub vendor: u32, +} + +impl VirtioDeviceId { + pub fn new(device: u32, vendor: u32) -> Self { + Self { device, vendor } + } +} diff --git a/kernel/src/driver/virtio/sysfs.rs b/kernel/src/driver/virtio/sysfs.rs index dc1d0ea1e..aab85e2c9 100644 --- a/kernel/src/driver/virtio/sysfs.rs +++ b/kernel/src/driver/virtio/sysfs.rs @@ -32,7 +32,7 @@ use crate::{ init::initcall::INITCALL_CORE, }; -use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver}; +use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_DEV_ANY_ID}; static mut VIRTIO_BUS: Option> = None; @@ -113,13 +113,38 @@ impl Bus for VirtIOBus { todo!() } + // 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#85 fn match_device( &self, _device: &Arc, _driver: &Arc, ) -> Result { - // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#85 - todo!("VirtIOBus::match_device() is not implemented") + let virtio_device = _device.clone().cast::().map_err(|_| { + error!( + "VirtIOBus::match_device() failed: device is not a VirtIODevice. Device: '{:?}'", + _device.name() + ); + SystemError::EINVAL + })?; + let virtio_driver = _driver.clone().cast::().map_err(|_| { + error!( + "VirtIOBus::match_device() failed: driver is not a VirtioDriver. Driver: '{:?}'", + _driver.name() + ); + SystemError::EINVAL + })?; + + let ids = virtio_driver.virtio_id_table(); + for id in &ids { + if id.device != virtio_device.device_type_id() && id.vendor != VIRTIO_DEV_ANY_ID { + continue; + } + if id.vendor == VIRTIO_DEV_ANY_ID || id.vendor == virtio_device.vendor() { + return Ok(true); + } + } + + return Ok(false); } } @@ -165,19 +190,10 @@ impl VirtIODeviceManager { pub fn device_add(&self, dev: Arc) -> Result<(), SystemError> { dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc)))); device_manager().device_default_initialize(&(dev.clone() as Arc)); - let drv = dev.driver().ok_or(SystemError::EINVAL)?; - let virtio_drv = drv.cast::().map_err(|_| { - error!( - "VirtIODeviceManager::device_add() failed: device.driver() is not a VirtioDriver. Device: '{:?}'", - dev.name() - ); - SystemError::EINVAL - })?; let virtio_index = VIRTIO_DEVICE_INDEX_MANAGER.alloc(); dev.set_virtio_device_index(virtio_index); dev.set_device_name(format!("virtio{}", virtio_index.data())); - virtio_drv.probe(&dev)?; device_manager().add_device(dev.clone() as Arc)?; let r = device_manager() diff --git a/kernel/src/driver/virtio/virtio.rs b/kernel/src/driver/virtio/virtio.rs index 9253542ef..c21592e69 100644 --- a/kernel/src/driver/virtio/virtio.rs +++ b/kernel/src/driver/virtio/virtio.rs @@ -1,16 +1,19 @@ use super::mmio::virtio_probe_mmio; use super::transport_pci::PciTransport; use super::virtio_impl::HalImpl; -use crate::driver::base::device::DeviceId; +use crate::driver::base::device::bus::Bus; +use crate::driver::base::device::{Device, DeviceId}; use crate::driver::block::virtio_blk::virtio_blk; use crate::driver::net::virtio_net::virtio_net; use crate::driver::pci::pci::{ get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure, PciDeviceStructureGeneralDevice, PCI_DEVICE_LINKEDLIST, }; +use crate::driver::pci::subsys::pci_bus; use crate::driver::virtio::transport::VirtIOTransport; use crate::libs::rwlock::RwLockWriteGuard; +use alloc::string::String; use alloc::sync::Arc; use alloc::vec::Vec; use alloc::{boxed::Box, collections::LinkedList}; @@ -39,7 +42,11 @@ fn virtio_probe_pci() { transport.read_device_features(), ); let transport = VirtIOTransport::Pci(transport); - virtio_device_init(transport, dev_id); + // 这里暂时通过设备名称在sysfs中查找设备,但是我感觉用设备ID更好 + let bus = pci_bus() as Arc; + let name: String = virtio_device.common_header.bus_device_function.into(); + let pci_raw_device = bus.find_device_by_name(name.as_str()); + virtio_device_init(transport, dev_id, pci_raw_device); } Err(err) => { error!("Pci transport create failed because of error: {}", err); @@ -49,16 +56,20 @@ fn virtio_probe_pci() { } ///@brief 为virtio设备寻找对应的驱动进行初始化 -pub(super) fn virtio_device_init(transport: VirtIOTransport, dev_id: Arc) { +pub(super) fn virtio_device_init( + transport: VirtIOTransport, + dev_id: Arc, + dev_parent: Option>, +) { match transport.device_type() { - DeviceType::Block => virtio_blk(transport, dev_id), + DeviceType::Block => virtio_blk(transport, dev_id, dev_parent), DeviceType::GPU => { warn!("Not support virtio_gpu device for now"); } DeviceType::Input => { warn!("Not support virtio_input device for now"); } - DeviceType::Network => virtio_net(transport, dev_id), + DeviceType::Network => virtio_net(transport, dev_id, dev_parent), t => { warn!("Unrecognized virtio device: {:?}", t); } diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index da1486da5..c74b0b58b 100644 --- a/kernel/src/net/net_core.rs +++ b/kernel/src/net/net_core.rs @@ -4,7 +4,7 @@ use smoltcp::{socket::dhcpv4, wire}; use system_error::SystemError; use crate::{ - driver::net::NetDevice, + driver::net::{NetDevice, Operstate}, libs::rwlock::RwLockReadGuard, net::{socket::SocketPollMethod, NET_DEVICES}, time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction}, @@ -89,6 +89,8 @@ fn dhcp_query() -> Result<(), SystemError> { .unwrap(); let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned(); if let Some(cidr) = cidr { + // 这里先在这里将网卡设置为up,后面等netlink实现了再修改 + net_face.set_operstate(Operstate::IF_OPER_UP); info!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr); return Ok(()); }