mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
feat(driver/net): 将网络设备注册到sysfs, 添加设备类属性文件 (#919)
This commit is contained in:
parent
a3571c8b79
commit
28fe4ad2a0
@ -163,6 +163,14 @@ impl Device for CmosRtcDevice {
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner().device_common.get_bus_weak_or_clear()
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for CmosRtcDevice {
|
||||
|
@ -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<Weak<dyn KObject>>,
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
kobject_common: KObjectCommonData,
|
||||
device_common: DeviceCommonData,
|
||||
name: String,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
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<Weak<dyn Bus>>) {
|
||||
self.inner.write().bus = bus;
|
||||
self.inner.write().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner.read().bus.clone()
|
||||
self.inner.read().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
@ -188,6 +182,14 @@ impl Device for CpuSubSystemFakeRootDevice {
|
||||
fn set_class(&self, _class: Option<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner.read().device_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.inner.write().kern_inode = inode;
|
||||
self.inner.write().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.read().kern_inode.clone()
|
||||
self.inner.read().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.read().parent_kobj.clone()
|
||||
self.inner.read().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.write().parent_kobj = parent;
|
||||
self.inner.write().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.read().kset.clone()
|
||||
self.inner.read().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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 {
|
||||
|
@ -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<dyn KObject>;
|
||||
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() {
|
||||
|
@ -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<Weak<dyn Device>>;
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>);
|
||||
}
|
||||
|
||||
impl dyn Device {
|
||||
@ -210,6 +222,7 @@ pub struct DeviceCommonData {
|
||||
pub driver: Option<Weak<dyn Driver>>,
|
||||
pub dead: bool,
|
||||
pub can_match: bool,
|
||||
pub parent: Option<Weak<dyn Device>>,
|
||||
}
|
||||
|
||||
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<Weak<dyn Driver>> {
|
||||
driver_base_macros::get_weak_or_clear!(self.driver)
|
||||
}
|
||||
|
||||
/// 获取parent字段
|
||||
///
|
||||
/// 当weak指针的strong count为0的时候,清除弱引用
|
||||
pub fn get_parent_weak_or_clear(&mut self) -> Option<Weak<dyn Device>> {
|
||||
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<dyn Device>) -> Result<(), SystemError> {
|
||||
// 在这里处理与parent相关的逻辑
|
||||
|
||||
let current_parent = device
|
||||
.parent()
|
||||
.and_then(|x| x.upgrade())
|
||||
.and_then(|x| x.arc_any().cast::<dyn Device>().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<dyn KObject>, 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<dyn Class>,
|
||||
kobject_parent: Arc<dyn KObject>,
|
||||
) -> Arc<dyn KObject> {
|
||||
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> = 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<dyn KObject>, 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<dyn Device>,
|
||||
current_parent: Option<Arc<dyn Device>>,
|
||||
device_parent: Option<Arc<dyn Device>>,
|
||||
) -> Result<Option<Arc<dyn KObject>>, SystemError> {
|
||||
// debug!("get_device_parent() device:{:?}", device.name());
|
||||
if device.class().is_some() {
|
||||
let parent_kobj: Arc<dyn KObject>;
|
||||
// debug!("current_parent:{:?}", current_parent);
|
||||
if let Some(cp) = current_parent {
|
||||
if cp.class().is_some() {
|
||||
return Ok(Some(cp.clone() as Arc<dyn KObject>));
|
||||
let kobject_parent: Arc<dyn KObject>;
|
||||
if let Some(dp) = device_parent {
|
||||
if dp.class().is_some() {
|
||||
return Ok(Some(dp.clone() as Arc<dyn KObject>));
|
||||
} else {
|
||||
parent_kobj = cp.clone() as Arc<dyn KObject>;
|
||||
kobject_parent = dp.clone() as Arc<dyn KObject>;
|
||||
}
|
||||
} else {
|
||||
parent_kobj = sys_devices_virtual_kset() as Arc<dyn KObject>;
|
||||
kobject_parent = sys_devices_virtual_kset() as Arc<dyn KObject>;
|
||||
}
|
||||
|
||||
// 是否需要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<dyn KObject>));
|
||||
@ -581,8 +640,8 @@ impl DeviceManager {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(current_parent) = current_parent {
|
||||
return Ok(Some(current_parent as Arc<dyn KObject>));
|
||||
if let Some(device_parent) = device_parent {
|
||||
return Ok(Some(device_parent as Arc<dyn KObject>));
|
||||
}
|
||||
|
||||
return Ok(None);
|
||||
@ -641,9 +700,8 @@ impl DeviceManager {
|
||||
let subsys_kobj = class.subsystem().subsys() as Arc<dyn KObject>;
|
||||
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<dyn KObject>;
|
||||
if let Some(dev_parent) = dev.dev_parent().and_then(|x| x.upgrade()) {
|
||||
let parent_kobj = dev_parent.clone() as Arc<dyn KObject>;
|
||||
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<BTreeMap<String, Arc<ClassDir>>> = RwLock::new(BTreeMap::new());
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClassDir {
|
||||
inner: SpinLock<InnerClassDir>,
|
||||
locked_kobj_state: LockedKObjectState,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct InnerClassDir {
|
||||
name: Option<String>,
|
||||
kobject_common: KObjectCommonData,
|
||||
}
|
||||
|
||||
impl ClassDir {
|
||||
fn new() -> Arc<Self> {
|
||||
return Arc::new(Self {
|
||||
inner: SpinLock::new(InnerClassDir {
|
||||
name: None,
|
||||
kobject_common: KObjectCommonData::default(),
|
||||
}),
|
||||
locked_kobj_state: LockedKObjectState::default(),
|
||||
});
|
||||
}
|
||||
|
||||
fn inner(&self) -> SpinLockGuard<InnerClassDir> {
|
||||
return self.inner.lock();
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for ClassDir {
|
||||
fn as_any_ref(&self) -> &dyn Any {
|
||||
return self;
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
return self.inner().kobject_common.kern_inode.clone();
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
return self.inner().kobject_common.parent.clone();
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
return self.inner().kobject_common.kset.clone();
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<KObjectState> {
|
||||
self.locked_kobj_state.read()
|
||||
}
|
||||
|
||||
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
|
||||
self.locked_kobj_state.write()
|
||||
}
|
||||
|
||||
fn set_kobj_state(&self, state: KObjectState) {
|
||||
*self.locked_kobj_state.write() = state;
|
||||
}
|
||||
}
|
||||
|
@ -178,18 +178,17 @@ impl SysFSOps for KObjectSysFSOps {
|
||||
pub struct KObjectManager;
|
||||
|
||||
impl KObjectManager {
|
||||
#[allow(dead_code)]
|
||||
pub fn init_and_add_kobj(
|
||||
kobj: Arc<dyn KObject>,
|
||||
join_kset: Option<Arc<KSet>>,
|
||||
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<dyn KObject>) {
|
||||
kobj.set_kobj_type(Some(&DynamicKObjKType));
|
||||
pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) {
|
||||
kobj.set_kobj_type(kobj_type);
|
||||
}
|
||||
|
||||
pub fn add_kobj(
|
||||
|
@ -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<dyn PlatformDevice>) -> Result<(), SystemError> {
|
||||
if pdev.parent().is_none() {
|
||||
pdev.set_parent(Some(Arc::downgrade(
|
||||
&(platform_bus_device() as Arc<dyn KObject>),
|
||||
if pdev.dev_parent().is_none() {
|
||||
pdev.set_dev_parent(Some(Arc::downgrade(
|
||||
&(platform_bus_device() as Arc<dyn Device>),
|
||||
)));
|
||||
}
|
||||
|
||||
@ -136,10 +136,12 @@ impl PlatformBusDevice {
|
||||
data: DevicePrivateData,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
) -> Arc<PlatformBusDevice> {
|
||||
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<InnerPlatformBusDevice> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct InnerPlatformBusDevice {
|
||||
name: String,
|
||||
data: DevicePrivateData,
|
||||
state: BusState, // 总线状态
|
||||
parent: Option<Weak<dyn KObject>>, // 总线的父对象
|
||||
|
||||
kernfs_inode: Option<Arc<KernFSInode>>,
|
||||
/// 当前设备挂载到的总线
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
/// 当前设备已经匹配的驱动
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
|
||||
ktype: Option<&'static dyn KObjType>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
kobject_common: KObjectCommonData,
|
||||
device_common: DeviceCommonData,
|
||||
}
|
||||
|
||||
impl InnerPlatformBusDevice {
|
||||
pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> 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<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kernfs_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
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<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
|
||||
@ -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<Arc<KSet>>) {
|
||||
self.inner.lock().kset = kset;
|
||||
self.inner().kobject_common.kset = kset;
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,15 +282,15 @@ impl Device for PlatformBusDevice {
|
||||
}
|
||||
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner.lock().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
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<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
fn set_class(&self, class: Option<Weak<dyn Class>>) {
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = dev_parent;
|
||||
}
|
||||
}
|
||||
|
@ -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<Weak<dyn Device>> {
|
||||
let root_device = platform_bus_device() as Arc<dyn Device>;
|
||||
return Some(Arc::downgrade(&root_device));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -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<Arc<VirtIOBlkDriver>> = None;
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(dead_code)]
|
||||
fn virtio_blk_driver() -> Arc<VirtIOBlkDriver> {
|
||||
unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() }
|
||||
}
|
||||
@ -63,9 +66,16 @@ pub fn virtio_blk_0() -> Option<Arc<VirtIOBlkDevice>> {
|
||||
.map(|dev| dev.arc_any().downcast().unwrap())
|
||||
}
|
||||
|
||||
pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
|
||||
pub fn virtio_blk(
|
||||
transport: VirtIOTransport,
|
||||
dev_id: Arc<DeviceId>,
|
||||
dev_parent: Option<Arc<dyn Device>>,
|
||||
) {
|
||||
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<dyn VirtIODevice>)
|
||||
.expect("Add virtio blk failed");
|
||||
@ -178,10 +188,6 @@ impl VirtIOBlkDevice {
|
||||
}),
|
||||
});
|
||||
|
||||
dev.set_driver(Some(Arc::downgrade(
|
||||
&(virtio_blk_driver() as Arc<dyn Driver>),
|
||||
)));
|
||||
|
||||
Some(dev)
|
||||
}
|
||||
|
||||
@ -393,6 +399,14 @@ impl Device for VirtIOBlkDevice {
|
||||
fn state_synced(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for VirtIOBlkDevice {
|
||||
@ -477,13 +491,22 @@ struct VirtIOBlkDriver {
|
||||
impl VirtIOBlkDriver {
|
||||
pub fn new() -> Arc<Self> {
|
||||
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<InnerVirtIOBlkDriver> {
|
||||
@ -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<dyn BlockDevice>)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn virtio_id_table(&self) -> LinkedList<crate::driver::virtio::VirtioDeviceId> {
|
||||
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 {
|
||||
|
@ -509,6 +509,14 @@ impl Device for LockedAhciDisk {
|
||||
fn set_class(&self, _class: Option<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, _dev_parent: Option<Weak<dyn Device>>) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockDevice for LockedAhciDisk {
|
||||
|
@ -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<InnerPs2MouseDevice> {
|
||||
self.inner.lock_irqsave()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InnerPs2MouseDevice {
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
class: Option<Weak<dyn Class>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
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<alloc::sync::Weak<dyn Bus>>) {
|
||||
self.inner.lock_irqsave().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn set_class(&self, class: Option<alloc::sync::Weak<dyn Class>>) {
|
||||
self.inner.lock_irqsave().class = class;
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<alloc::sync::Arc<dyn Driver>> {
|
||||
self.inner.lock_irqsave().driver.clone()?.upgrade()
|
||||
self.inner().device_common.driver.clone()?.upgrade()
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>) {
|
||||
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<alloc::sync::Weak<dyn Bus>> {
|
||||
self.inner.lock_irqsave().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<alloc::sync::Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>) {
|
||||
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<alloc::sync::Arc<KernFSInode>>) {
|
||||
self.inner.lock_irqsave().kern_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<alloc::sync::Arc<KernFSInode>> {
|
||||
self.inner.lock_irqsave().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
|
||||
self.inner.lock_irqsave().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
|
||||
self.inner.lock_irqsave().parent = parent
|
||||
self.inner().kobject_common.parent = parent
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<alloc::sync::Arc<KSet>> {
|
||||
self.inner.lock_irqsave().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<alloc::sync::Arc<KSet>>) {
|
||||
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<dyn KObject>) -> Result<(), SystemError> {
|
||||
pub fn rs_ps2_mouse_device_init(dev_parent: Arc<dyn Device>) -> Result<(), SystemError> {
|
||||
debug!("ps2_mouse_device initializing...");
|
||||
let psmouse = Arc::new(Ps2MouseDevice::new());
|
||||
|
||||
device_manager().device_default_initialize(&(psmouse.clone() as Arc<dyn Device>));
|
||||
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<dyn SerioDevice>)?;
|
||||
|
||||
devfs_register(&psmouse.name(), psmouse.clone()).map_err(|e| {
|
||||
|
@ -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<InnerI8042PlatformDevice> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InnerI8042PlatformDevice {
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
class: Option<Weak<dyn Class>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
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<Weak<dyn Bus>> {
|
||||
self.inner.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner.lock().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Weak<dyn Class>>) {
|
||||
self.inner.lock().class = class;
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
self.inner.lock().driver.clone()?.upgrade()
|
||||
self.inner().device_common.driver.clone()?.upgrade()
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.inner.lock().kern_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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 {
|
||||
|
@ -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<Weak<dyn Bus>>,
|
||||
class: Option<Weak<dyn Class>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
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<InnerI8042AuxPort> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
impl Device for I8042AuxPort {
|
||||
@ -69,32 +63,32 @@ impl Device for I8042AuxPort {
|
||||
}
|
||||
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner.lock().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn set_class(&self, class: Option<Weak<dyn Class>>) {
|
||||
self.inner.lock().class = class;
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Arc<dyn Driver>> {
|
||||
self.inner.lock().driver.clone()?.upgrade()
|
||||
self.inner().device_common.driver.clone()?.upgrade()
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for I8042AuxPort {
|
||||
@ -118,35 +120,35 @@ impl KObject for I8042AuxPort {
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
self.inner.lock().kern_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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 {
|
||||
|
@ -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<dyn SerioDevice>) -> 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<dyn KObject>),
|
||||
aux_port.set_dev_parent(Some(Arc::downgrade(
|
||||
&(i8042_platform_device() as Arc<dyn Device>),
|
||||
)));
|
||||
serio_device_manager().register_port(aux_port.clone() as Arc<dyn SerioDevice>)?;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
crate::driver::input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init(
|
||||
aux_port.clone() as Arc<dyn KObject>
|
||||
aux_port.clone() as Arc<dyn Device>
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
83
kernel/src/driver/net/class.rs
Normal file
83
kernel/src/driver/net/class.rs
Normal file
@ -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<Arc<NetClass>> = None;
|
||||
|
||||
/// 获取 `/sys/class/net` 的 class 实例
|
||||
#[inline(always)]
|
||||
#[allow(dead_code)]
|
||||
pub fn sys_class_net_instance() -> Option<&'static Arc<NetClass>> {
|
||||
unsafe { CLASS_NET_INSTANCE.as_ref() }
|
||||
}
|
||||
|
||||
/// 初始化net子系统
|
||||
#[unified_init(INITCALL_SUBSYS)]
|
||||
pub fn net_init() -> Result<(), SystemError> {
|
||||
let net_class: Arc<NetClass> = NetClass::new();
|
||||
class_manager().class_register(&(net_class.clone() as Arc<dyn Class>))?;
|
||||
|
||||
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<Self> {
|
||||
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<dyn Class>));
|
||||
|
||||
return net_class;
|
||||
}
|
||||
}
|
||||
|
||||
impl Class for NetClass {
|
||||
fn name(&self) -> &'static str {
|
||||
return Self::NAME;
|
||||
}
|
||||
|
||||
fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
|
||||
Some(sys_dev_char_kset() as Arc<dyn KObject>)
|
||||
}
|
||||
|
||||
fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
|
||||
unimplemented!("NetClass::set_dev_kobj");
|
||||
}
|
||||
|
||||
fn subsystem(&self) -> &SubSysPrivate {
|
||||
return &self.subsystem;
|
||||
}
|
||||
|
||||
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
|
||||
return &[&NetAttrGroup];
|
||||
}
|
||||
}
|
@ -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<smoltcp::iface::Interface>,
|
||||
name: String,
|
||||
inner: SpinLock<InnerE1000EInterface>,
|
||||
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<R, F>(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<InnerE1000EInterface> {
|
||||
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 set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
|
||||
todo!()
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_class(&self, _class: Option<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Weak<dyn Class>>) {
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
todo!()
|
||||
let r = self.inner().device_common.driver.clone()?.upgrade();
|
||||
if r.is_none() {
|
||||
self.inner().device_common.driver = None;
|
||||
}
|
||||
|
||||
fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
|
||||
todo!()
|
||||
return r;
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
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<smoltcp::iface::Interface> {
|
||||
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<Arc<crate::filesystem::kernfs::KernFSInode>>) {
|
||||
todo!()
|
||||
fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
|
||||
self.inner().kobj_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
|
||||
todo!()
|
||||
self.inner().kobj_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
|
||||
todo!()
|
||||
self.inner().kobj_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
|
||||
todo!()
|
||||
fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
|
||||
self.inner().kobj_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
|
||||
todo!()
|
||||
self.inner().kobj_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
|
||||
todo!()
|
||||
fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
|
||||
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<crate::driver::base::kobject::KObjectState> {
|
||||
todo!()
|
||||
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
|
||||
self.locked_kobj_state.read()
|
||||
}
|
||||
|
||||
fn kobj_state_mut(
|
||||
&self,
|
||||
) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
|
||||
todo!()
|
||||
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
|
||||
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");
|
||||
}
|
||||
|
@ -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<smoltcp::iface::Interface>,
|
||||
name: String,
|
||||
inner: SpinLock<InnerLoopbackInterface>,
|
||||
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<InnerLoopbackInterface> {
|
||||
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<Arc<crate::filesystem::kernfs::KernFSInode>>) {
|
||||
todo!()
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
self.inner().kobj_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
|
||||
todo!()
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner().kobj_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
|
||||
todo!()
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner().kobj_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
|
||||
todo!()
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner().kobj_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
|
||||
todo!()
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner().kobj_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
|
||||
todo!()
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<crate::driver::base::kobject::KObjectState> {
|
||||
todo!()
|
||||
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
|
||||
self.locked_kobj_state.read()
|
||||
}
|
||||
|
||||
fn kobj_state_mut(
|
||||
&self,
|
||||
) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
|
||||
todo!()
|
||||
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
|
||||
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<Weak<dyn Bus>>) {
|
||||
todo!()
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_class(&self, _class: Option<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Weak<dyn Class>>) {
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
todo!()
|
||||
let r = self.inner().device_common.driver.clone()?.upgrade();
|
||||
if r.is_none() {
|
||||
self.inner().device_common.driver = None;
|
||||
}
|
||||
|
||||
fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
|
||||
todo!()
|
||||
return r;
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
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<smoltcp::iface::Interface> {
|
||||
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网卡设备的注册函数
|
||||
|
@ -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<smoltcp::iface::Interface>;
|
||||
// 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<dyn NetDevice>) -> Result<(), SystemError> {
|
||||
// 在sysfs中注册设备
|
||||
netdev_register_kobject(dev.clone())?;
|
||||
|
||||
// 标识网络设备在系统中存在
|
||||
dev.set_net_state(NetDeivceState::__LINK_STATE_PRESENT);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
635
kernel/src/driver/net/sysfs.rs
Normal file
635
kernel/src/driver/net/sysfs.rs
Normal file
@ -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<dyn NetDevice>) -> Result<(), SystemError> {
|
||||
// 初始化设备
|
||||
device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
|
||||
|
||||
// 设置dev的class为net
|
||||
dev.set_class(Some(Arc::downgrade(
|
||||
&(sys_class_net_instance().cloned().unwrap() as Arc<dyn Class>),
|
||||
)));
|
||||
|
||||
// 设置设备的kobject名
|
||||
dev.set_name(dev.iface_name().clone());
|
||||
|
||||
device_manager().add_device(dev.clone() as Arc<dyn Device>)?;
|
||||
|
||||
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<dyn KObject>,
|
||||
attr: &'static dyn Attribute,
|
||||
) -> Option<ModeType> {
|
||||
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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let net_device = kobj.cast::<dyn NetDevice>().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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrIfalias::show")
|
||||
}
|
||||
|
||||
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let net_deive = kobj.cast::<dyn NetDevice>().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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let net_device = kobj.cast::<dyn NetDevice>().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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let net_device = kobj.cast::<dyn NetDevice>().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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let net_device = _kobj.cast::<dyn NetDevice>().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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrMtu::show")
|
||||
}
|
||||
|
||||
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrFlags::show")
|
||||
}
|
||||
|
||||
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrTxQueueLen::show")
|
||||
}
|
||||
|
||||
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||
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<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrNetdevGroup::show")
|
||||
}
|
||||
|
||||
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||
todo!("AttrNetdevGroup::store")
|
||||
}
|
||||
}
|
@ -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<Arc<VirtIONetDriver>> = None;
|
||||
|
||||
const DEVICE_NAME: &str = "virtio_net";
|
||||
const VIRTIO_NET_BASENAME: &str = "virtio_net";
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(dead_code)]
|
||||
fn virtio_net_driver() -> Arc<VirtIONetDriver> {
|
||||
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<DeviceId>,
|
||||
inner: SpinLock<InnerVirtIONetDevice>,
|
||||
locked_kobj_state: LockedKObjectState,
|
||||
}
|
||||
|
||||
unsafe impl Send for VirtIONetDevice {}
|
||||
unsafe impl Sync for VirtIONetDevice {}
|
||||
|
||||
struct InnerVirtIONetDevice {
|
||||
device_inner: VirtIONicDeviceInner,
|
||||
name: Option<String>,
|
||||
virtio_index: Option<VirtIODeviceIndex>,
|
||||
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<DeviceId>) -> Option<Arc<Self>> {
|
||||
let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
||||
match VirtIONet::<HalImpl, VirtIOTransport, 2>::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<dyn Driver>));
|
||||
|
||||
return Some(dev);
|
||||
}
|
||||
|
||||
fn inner(&self) -> SpinLockGuard<InnerVirtIONetDevice> {
|
||||
return self.inner.lock();
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for VirtIONetDevice {
|
||||
fn as_any_ref(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
self.inner().kobj_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner().kobj_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner().kobj_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner().kobj_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner().kobj_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<KObjectState> {
|
||||
self.locked_kobj_state.read()
|
||||
}
|
||||
|
||||
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
|
||||
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<Weak<dyn Bus>> {
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Weak<dyn Class>>) {
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
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<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtIODevice for VirtIONetDevice {
|
||||
fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
||||
poll_ifaces_try_lock_onetime().ok();
|
||||
return Ok(IrqReturn::Handled);
|
||||
}
|
||||
|
||||
fn dev_id(&self) -> &Arc<DeviceId> {
|
||||
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<VirtIODeviceIndex> {
|
||||
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<IrqNumber> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VirtIoNetImpl {
|
||||
inner: VirtIONet<HalImpl, VirtIOTransport, 2>,
|
||||
}
|
||||
@ -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<DeviceId>,
|
||||
iface: SpinLock<iface::Interface>,
|
||||
inner: SpinLock<InnerVirtIOInterface>,
|
||||
locked_kobj_state: LockedKObjectState,
|
||||
@ -141,10 +374,9 @@ pub struct VirtioInterface {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InnerVirtIOInterface {
|
||||
name: Option<String>,
|
||||
virtio_index: Option<VirtIODeviceIndex>,
|
||||
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<DeviceId>) -> Arc<Self> {
|
||||
pub fn new(mut device_inner: VirtIONicDeviceInner) -> Arc<Self> {
|
||||
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<dyn Driver>);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -201,47 +427,6 @@ impl VirtioInterface {
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtIODevice for VirtioInterface {
|
||||
fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
||||
poll_ifaces_try_lock_onetime().ok();
|
||||
return Ok(IrqReturn::Handled);
|
||||
}
|
||||
|
||||
fn irq(&self) -> Option<IrqNumber> {
|
||||
None
|
||||
}
|
||||
|
||||
fn dev_id(&self) -> &Arc<DeviceId> {
|
||||
return &self.dev_id;
|
||||
}
|
||||
fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
|
||||
self.inner().virtio_index = Some(index);
|
||||
}
|
||||
|
||||
fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
|
||||
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<Weak<dyn Bus>> {
|
||||
@ -308,6 +493,14 @@ impl Device for VirtioInterface {
|
||||
fn state_synced(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtIONicDeviceInner {
|
||||
@ -413,23 +606,22 @@ impl phy::RxToken for VirtioNetToken {
|
||||
}
|
||||
|
||||
/// @brief virtio-net 驱动的初始化与测试
|
||||
pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
|
||||
let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
||||
match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
||||
Ok(net) => net,
|
||||
Err(_) => {
|
||||
error!("VirtIONet init failed");
|
||||
return;
|
||||
pub fn virtio_net(
|
||||
transport: VirtIOTransport,
|
||||
dev_id: Arc<DeviceId>,
|
||||
dev_parent: Option<Arc<dyn Device>>,
|
||||
) {
|
||||
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)));
|
||||
}
|
||||
};
|
||||
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<dyn VirtIODevice>)
|
||||
.device_add(virtio_net_deivce.clone() as Arc<dyn VirtIODevice>)
|
||||
.expect("Add virtio net failed");
|
||||
}
|
||||
}
|
||||
|
||||
impl NetDevice for VirtioInterface {
|
||||
fn mac(&self) -> wire::EthernetAddress {
|
||||
@ -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<Self> {
|
||||
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<InnerVirtIODriver> {
|
||||
@ -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<dyn VirtIODevice>) -> Result<(), SystemError> {
|
||||
let iface = device
|
||||
log::debug!("VirtIONetDriver::probe()");
|
||||
let virtio_net_device = device
|
||||
.clone()
|
||||
.arc_any()
|
||||
.downcast::<VirtioInterface>()
|
||||
.downcast::<VirtIONetDevice>()
|
||||
.map_err(|_| {
|
||||
error!(
|
||||
"VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'",
|
||||
"VirtIONetDriver::probe() failed: device is not a VirtIODevice. Device: '{:?}'",
|
||||
device.name()
|
||||
);
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
|
||||
let iface: Arc<VirtioInterface> =
|
||||
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<dyn Device>));
|
||||
// 在sysfs中注册iface
|
||||
register_netdevice(iface.clone() as Arc<dyn NetDevice>)?;
|
||||
|
||||
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
||||
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<VirtioDeviceId> {
|
||||
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<IdTable> {
|
||||
Some(IdTable::new(DEVICE_NAME.to_string(), None))
|
||||
Some(IdTable::new(VIRTIO_NET_BASENAME.to_string(), None))
|
||||
}
|
||||
|
||||
fn add_device(&self, device: Arc<dyn Device>) {
|
||||
let iface = device
|
||||
let virtio_net_device = device
|
||||
.arc_any()
|
||||
.downcast::<VirtioInterface>()
|
||||
.downcast::<VirtIONetDevice>()
|
||||
.expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface");
|
||||
|
||||
self.inner()
|
||||
.driver_common
|
||||
.devices
|
||||
.push(iface as Arc<dyn Device>);
|
||||
.push(virtio_net_device as Arc<dyn Device>);
|
||||
}
|
||||
|
||||
fn delete_device(&self, device: &Arc<dyn Device>) {
|
||||
let _iface = device
|
||||
let _virtio_net_device = device
|
||||
.clone()
|
||||
.arc_any()
|
||||
.downcast::<VirtioInterface>()
|
||||
.downcast::<VirtIONetDevice>()
|
||||
.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) {
|
||||
|
@ -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<dyn PciDevice>) -> 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<dyn KObject>),
|
||||
)));
|
||||
if pci_dev.dev_parent().is_none() {
|
||||
pci_dev.set_dev_parent(Some(Arc::downgrade(&(pci_bus_device() as Arc<dyn Device>))));
|
||||
}
|
||||
// 设置设备的总线
|
||||
pci_dev.set_bus(Some(Arc::downgrade(&(pci_bus() as Arc<dyn Bus>))));
|
||||
@ -90,26 +91,34 @@ pub trait PciDevice: Device {
|
||||
#[derive(Debug)]
|
||||
#[cast_to([sync] Device)]
|
||||
pub struct PciBusDevice {
|
||||
// inner: SpinLock<InnerPciBusDevice>,
|
||||
device_data: SpinLock<DeviceCommonData>,
|
||||
kobj_data: SpinLock<KObjectCommonData>,
|
||||
inner: SpinLock<InnerPciBusDevice>,
|
||||
kobj_state: LockedKObjectState,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl PciBusDevice {
|
||||
pub fn new(parent: Option<Weak<dyn KObject>>) -> Arc<Self> {
|
||||
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<InnerPciBusDevice> {
|
||||
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<alloc::sync::Weak<dyn KObject>> {
|
||||
self.kobj_data.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.kobj_data.lock().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
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<Arc<KSet>> {
|
||||
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<Arc<KSet>>) {
|
||||
self.kobj_data.lock().kset = kset;
|
||||
self.inner().kobject_common.kset = kset;
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.kobj_data.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,15 +191,15 @@ impl Device for PciBusDevice {
|
||||
}
|
||||
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.device_data.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
|
||||
self.device_data.lock().bus = bus
|
||||
self.inner().device_common.bus = bus
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
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<alloc::sync::Weak<dyn Driver>>) {
|
||||
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<alloc::sync::Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = dev_parent;
|
||||
}
|
||||
}
|
||||
|
@ -24,31 +24,36 @@ use super::{
|
||||
#[cast_to([sync] Device)]
|
||||
#[cast_to([sync] PciDevice)]
|
||||
pub struct PciGeneralDevice {
|
||||
device_data: RwLock<DeviceCommonData>,
|
||||
kobj_data: RwLock<KObjectCommonData>,
|
||||
name: RwLock<Option<String>>,
|
||||
inner: RwLock<InnerPciGeneralDevice>,
|
||||
kobj_state: LockedKObjectState,
|
||||
dev_id: PciDeviceID,
|
||||
header: Arc<PciDeviceStructureGeneralDevice>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InnerPciGeneralDevice {
|
||||
name: Option<String>,
|
||||
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<Weak<dyn Bus>> {
|
||||
self.device_data.read().bus.clone()
|
||||
self.inner.read().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Arc<dyn Driver>> {
|
||||
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<Weak<dyn Bus>>) {
|
||||
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<Weak<dyn Class>>) {
|
||||
self.device_data.write().class = class;
|
||||
self.inner.write().device_common.class = class;
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
self.device_data.write().driver = driver
|
||||
self.inner.write().device_common.driver = driver
|
||||
}
|
||||
|
||||
fn state_synced(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner.write().device_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.kobj_data.write().kern_inode = inode;
|
||||
self.inner.write().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.kobj_data.read().kern_inode.clone()
|
||||
self.inner.read().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.kobj_data.read().parent.clone()
|
||||
self.inner.read().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.kobj_data.write().parent = parent;
|
||||
self.inner.write().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.kobj_data.read().kset.clone()
|
||||
self.inner.read().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<KObjectState> {
|
||||
|
@ -151,6 +151,11 @@ impl Bus for PciBus {
|
||||
};
|
||||
return Ok(pci_dev.name().eq(&pci_driver.name()));
|
||||
}
|
||||
|
||||
fn root_device(&self) -> Option<Weak<dyn Device>> {
|
||||
let root_device = pci_bus_device() as Arc<dyn Device>;
|
||||
return Some(Arc::downgrade(&root_device));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -130,6 +130,14 @@ impl Device for TestDevice {
|
||||
fn state_synced(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.device_data.read().parent.clone()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
self.device_data.write().parent = dev_parent
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for TestDevice {
|
||||
|
@ -173,6 +173,14 @@ impl Device for RtcGeneralDevice {
|
||||
fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
|
||||
Some(&[&RtcAttrGroup])
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = dev_parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for RtcGeneralDevice {
|
||||
@ -245,7 +253,7 @@ pub fn rtc_general_device_create(
|
||||
) -> Arc<RtcGeneralDevice> {
|
||||
let dev = RtcGeneralDevice::new(priority.unwrap_or_default());
|
||||
device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
|
||||
dev.set_parent(Some(Arc::downgrade(real_dev) as Weak<dyn KObject>));
|
||||
dev.set_dev_parent(Some(Arc::downgrade(real_dev) as Weak<dyn Device>));
|
||||
dev.set_class(Some(Arc::downgrade(
|
||||
&(sys_class_rtc_instance().cloned().unwrap() as Arc<dyn Class>),
|
||||
)));
|
||||
|
@ -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<Weak<dyn Bus>> {
|
||||
self.inner.read().bus.clone()
|
||||
self.inner.read().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
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<Arc<dyn Driver>> {
|
||||
self.inner.read().driver.clone()?.upgrade()
|
||||
self.inner.read().device_common.driver.clone()?.upgrade()
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Class>>) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
||||
self.inner.read().device_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.inner.write().inode = inode;
|
||||
self.inner.write().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.read().inode.clone()
|
||||
self.inner.read().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.read().parent_kobj.clone()
|
||||
self.inner.read().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.write().parent_kobj = parent;
|
||||
self.inner.write().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.read().kset.clone()
|
||||
self.inner.read().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<Arc<KSet>>,
|
||||
parent_kobj: Option<Weak<dyn KObject>>,
|
||||
/// 当前设备所述的总线
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
inode: Option<Arc<KernFSInode>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -549,6 +549,17 @@ impl Device for TtyDevice {
|
||||
fn state_synced(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_dev_parent(
|
||||
&self,
|
||||
_dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl CharDevice for TtyDevice {
|
||||
|
@ -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<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
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<Self> {
|
||||
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<InnerFbConsoleDevice> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for FbConsoleDevice {
|
||||
@ -129,35 +128,35 @@ impl KObject for FbConsoleDevice {
|
||||
}
|
||||
|
||||
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
||||
self.inner.lock().kernfs_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kernfs_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<Weak<dyn Bus>>) {
|
||||
self.inner.lock().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
||||
self.inner.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_class(&self, _class: Option<Weak<dyn Class>>) {
|
||||
@ -208,27 +207,27 @@ impl Device for FbConsoleDevice {
|
||||
}
|
||||
|
||||
fn driver(&self) -> Option<Arc<dyn Driver>> {
|
||||
self.inner
|
||||
.lock()
|
||||
self.inner()
|
||||
.device_common
|
||||
.driver
|
||||
.clone()
|
||||
.and_then(|driver| driver.upgrade())
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = dev_parent;
|
||||
}
|
||||
}
|
||||
|
||||
/// framebuffer console设备的匿名属性组
|
||||
|
@ -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<dyn FrameBuffer>, id);
|
||||
device_manager().device_default_initialize(&(fb_device.clone() as Arc<dyn Device>));
|
||||
fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc<dyn KObject>))));
|
||||
fb_device.set_dev_parent(Some(Arc::downgrade(&(fb.clone() as Arc<dyn Device>))));
|
||||
|
||||
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<InnerFbDevice> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InnerFbDevice {
|
||||
fb: Weak<dyn FrameBuffer>,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.inner.lock().kern_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
self.inner().device_common.parent = dev_parent;
|
||||
}
|
||||
}
|
||||
|
||||
impl DeviceINode for FbDevice {
|
||||
|
@ -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<InnerVesaFb> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InnerVesaFb {
|
||||
bus: Option<Weak<dyn Bus>>,
|
||||
class: Option<Weak<dyn Class>>,
|
||||
driver: Option<Weak<dyn Driver>>,
|
||||
kern_inode: Option<Arc<KernFSInode>>,
|
||||
parent: Option<Weak<dyn KObject>>,
|
||||
kset: Option<Arc<KSet>>,
|
||||
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<Weak<dyn Bus>> {
|
||||
self.inner.lock().bus.clone()
|
||||
self.inner().device_common.bus.clone()
|
||||
}
|
||||
|
||||
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
||||
self.inner.lock().bus = bus;
|
||||
self.inner().device_common.bus = bus;
|
||||
}
|
||||
|
||||
fn set_class(&self, class: Option<Weak<dyn Class>>) {
|
||||
self.inner.lock().class = class;
|
||||
self.inner().device_common.class = class;
|
||||
}
|
||||
|
||||
fn class(&self) -> Option<Arc<dyn Class>> {
|
||||
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<Arc<dyn Driver>> {
|
||||
self.inner.lock().driver.clone()?.upgrade()
|
||||
self.inner().device_common.driver.clone()?.upgrade()
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
||||
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<Weak<dyn Device>> {
|
||||
self.inner().device_common.get_parent_weak_or_clear()
|
||||
}
|
||||
|
||||
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
|
||||
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<Arc<KernFSInode>>) {
|
||||
self.inner.lock().kern_inode = inode;
|
||||
self.inner().kobject_common.kern_inode = inode;
|
||||
}
|
||||
|
||||
fn inode(&self) -> Option<Arc<KernFSInode>> {
|
||||
self.inner.lock().kern_inode.clone()
|
||||
self.inner().kobject_common.kern_inode.clone()
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Weak<dyn KObject>> {
|
||||
self.inner.lock().parent.clone()
|
||||
self.inner().kobject_common.parent.clone()
|
||||
}
|
||||
|
||||
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
||||
self.inner.lock().parent = parent;
|
||||
self.inner().kobject_common.parent = parent;
|
||||
}
|
||||
|
||||
fn kset(&self) -> Option<Arc<KSet>> {
|
||||
self.inner.lock().kset.clone()
|
||||
self.inner().kobject_common.kset.clone()
|
||||
}
|
||||
|
||||
fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
||||
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 {
|
||||
|
@ -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(())
|
||||
};
|
||||
|
||||
|
@ -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<dyn VirtIODevice>) -> Result<(), SystemError>;
|
||||
|
||||
fn virtio_id_table(&self) -> LinkedList<VirtioDeviceId>;
|
||||
|
||||
fn add_virtio_id(&self, id: VirtioDeviceId);
|
||||
}
|
||||
|
||||
int_like!(VirtIODeviceIndex, usize);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct VirtIODriverCommonData {
|
||||
pub id_table: LinkedList<VirtioDeviceId>,
|
||||
}
|
||||
|
||||
/// 参考: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 }
|
||||
}
|
||||
}
|
||||
|
@ -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<Arc<VirtIOBus>> = 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<dyn Device>,
|
||||
_driver: &Arc<dyn Driver>,
|
||||
) -> Result<bool, SystemError> {
|
||||
// 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::<dyn VirtIODevice>().map_err(|_| {
|
||||
error!(
|
||||
"VirtIOBus::match_device() failed: device is not a VirtIODevice. Device: '{:?}'",
|
||||
_device.name()
|
||||
);
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
let virtio_driver = _driver.clone().cast::<dyn VirtIODriver>().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<dyn VirtIODevice>) -> Result<(), SystemError> {
|
||||
dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
|
||||
device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
|
||||
let drv = dev.driver().ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let virtio_drv = drv.cast::<dyn VirtIODriver>().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<dyn Device>)?;
|
||||
let r = device_manager()
|
||||
|
@ -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<dyn Bus>;
|
||||
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<DeviceId>) {
|
||||
pub(super) fn virtio_device_init(
|
||||
transport: VirtIOTransport,
|
||||
dev_id: Arc<DeviceId>,
|
||||
dev_parent: Option<Arc<dyn Device>>,
|
||||
) {
|
||||
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);
|
||||
}
|
||||
|
@ -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(());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user