设备驱动模型:完善platform bus相关内容。并注册串口到sysfs (#403)

* 完成初始化platform bus
* 删除旧的sysfs
* 把uart驱动移动到tty/serial文件夹下
* 完成将串口挂载到sysfs
* 修复vfs系统调用未能follow symlink的问题
* 修复shell未能正确获取pwd的问题
This commit is contained in:
LoGin
2023-10-20 22:11:33 +08:00
committed by GitHub
parent 06d5e24726
commit a03c4f9dee
61 changed files with 2904 additions and 1325 deletions

View File

@ -74,8 +74,6 @@ pub fn platform_bus_init() -> Result<(), SystemError> {
let platform_device: Arc<PlatformBusDevice> = PlatformBusDevice::new(
DevicePrivateData::new(
IdTable::new("platform".to_string(), DeviceNumber::new(0)),
None,
CompatibleTable::new(vec!["platform"]),
BusState::NotInitialized.into(),
),
Some(Arc::downgrade(&(sys_devices_kset() as Arc<dyn KObject>))),

View File

@ -2,31 +2,64 @@ use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
};
use ida::IdAllocator;
use crate::{
driver::{
base::{
device::{
bus::{Bus, BusState},
Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
driver::base::{
device::{
bus::{Bus, BusState},
device_manager,
driver::Driver,
Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable,
},
Driver,
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
},
filesystem::kernfs::KernFSInode,
libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard},
spinlock::SpinLock,
},
syscall::SystemError,
};
use super::{super::device::DeviceState, CompatibleTable};
use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
/// 平台设备id分配器
static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(i32::MAX as usize);
#[inline(always)]
pub fn platform_device_manager() -> &'static PlatformDeviceManager {
&PlatformDeviceManager
}
/// 没有平台设备id
pub const PLATFORM_DEVID_NONE: i32 = -1;
/// 请求自动分配这个平台设备id
pub const PLATFORM_DEVID_AUTO: i32 = -2;
/// @brief: 实现该trait的设备实例应挂载在platform总线上
/// 同时应该实现Device trait
///
/// ## 注意
///
/// 应当在所有实现这个trait的结构体上方添加 `#[cast_to([sync] PlatformDriver)]`
/// 否则运行时将报错“该对象不是PlatformDriver”
pub trait PlatformDevice: Device {
fn pdev_name(&self) -> &str;
/// 返回平台设备id以及这个id是否是自动生成的
///
/// 请注意如果当前设备还没有id应该返回
/// (PLATFORM_DEVID_NONE, false)
fn pdev_id(&self) -> (i32, bool) {
(PLATFORM_DEVID_NONE, false)
}
/// 设置平台设备id
fn set_pdev_id(&self, id: i32);
/// 设置id是否为自动分配
fn set_pdev_id_auto(&self, id_auto: bool);
fn compatible_table(&self) -> CompatibleTable;
/// @brief: 判断设备是否初始化
/// @parameter: None
@ -39,6 +72,54 @@ pub trait PlatformDevice: Device {
fn set_state(&self, set_state: DeviceState);
}
#[derive(Debug)]
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>),
)));
}
pdev.set_bus(Some(platform_bus() as Arc<dyn Bus>));
let id = pdev.pdev_id().0;
match id {
PLATFORM_DEVID_NONE => {
pdev.set_name(format!("{}", pdev.pdev_name()));
}
PLATFORM_DEVID_AUTO => {
let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?;
pdev.set_pdev_id(id as i32);
pdev.set_pdev_id_auto(true);
pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0));
}
_ => {
pdev.set_name(format!("{}.{}", pdev.pdev_name(), id));
}
}
// todo: 插入资源: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=platform_device_add#691
let r = device_manager().add_device(pdev.clone() as Arc<dyn Device>);
if r.is_ok() {
pdev.set_state(DeviceState::Initialized);
return Ok(()); // success
} else {
// failed
let pdevid = pdev.pdev_id();
if pdevid.1 {
PLATFORM_DEVID_IDA.free(pdevid.0 as usize);
pdev.set_pdev_id(PLATFORM_DEVID_AUTO);
}
return r;
}
}
}
#[derive(Debug)]
#[cast_to([sync] Device)]
pub struct PlatformBusDevice {
@ -56,7 +137,7 @@ impl PlatformBusDevice {
) -> Arc<PlatformBusDevice> {
return Arc::new(PlatformBusDevice {
inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)),
kobj_state: LockedKObjectState::new(KObjectState::empty()),
kobj_state: LockedKObjectState::new(None),
});
}
@ -101,18 +182,8 @@ impl PlatformBusDevice {
let state = self.inner.lock().state;
return state;
}
// /// @brief:
// /// @parameter: None
// /// @return: 总线状态
// #[inline]
// #[allow(dead_code)]
// fn set_driver(&self, driver: Option<Arc<LockedPlatformBusDriver>>) {
// self.0.lock().driver = driver;
// }
}
/// @brief: platform总线
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct InnerPlatformBusDevice {
@ -125,14 +196,10 @@ pub struct InnerPlatformBusDevice {
/// 当前设备挂载到的总线
bus: Option<Arc<dyn Bus>>,
/// 当前设备已经匹配的驱动
driver: Option<Arc<dyn Driver>>,
driver: Option<Weak<dyn Driver>>,
}
/// @brief: platform方法集
impl InnerPlatformBusDevice {
/// @brief: 创建一个platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self {
Self {
data,
@ -167,6 +234,10 @@ impl KObject for PlatformBusDevice {
None
}
fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
todo!("platform_bus_device::set_kobj_type")
}
fn kset(&self) -> Option<Arc<KSet>> {
None
}
@ -218,8 +289,12 @@ impl Device for PlatformBusDevice {
self.inner.lock().bus.clone()
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
self.inner.lock().bus = bus;
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
self.inner.lock().driver.clone()
self.inner.lock().driver.clone()?.upgrade()
}
#[inline]
@ -227,7 +302,19 @@ impl Device for PlatformBusDevice {
false
}
fn set_driver(&self, driver: Option<Arc<dyn Driver>>) {
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
self.inner.lock().driver = driver;
}
fn can_match(&self) -> bool {
todo!()
}
fn set_can_match(&self, _can_match: bool) {
todo!()
}
fn state_synced(&self) -> bool {
todo!()
}
}

View File

@ -1,21 +1,54 @@
use crate::driver::{base::device::DevicePrivateData, Driver};
use alloc::sync::Arc;
use super::{super::device::driver::DriverError, CompatibleTable};
use crate::{
driver::base::device::{
bus::Bus,
driver::{driver_manager, Driver},
},
syscall::SystemError,
};
use super::{platform_bus, platform_device::PlatformDevice};
lazy_static! {
static ref PLATFORM_COMPAT_TABLE: CompatibleTable = CompatibleTable::new(vec!["platform"]);
}
/// @brief: 实现该trait的设备驱动实例应挂载在platform总线上
/// 同时应该实现Driver trait
///
/// ## 注意
///
/// 应当在所有实现这个trait的结构体上方添加 `#[cast_to([sync] PlatformDriver)]`
/// 否则运行时将报错“该对象不是PlatformDriver”
pub trait PlatformDriver: Driver {
fn compatible_table(&self) -> CompatibleTable;
/// @brief 探测设备
/// @param data 设备初始拥有的基本信息
fn probe(&self, data: DevicePrivateData) -> Result<(), DriverError> {
if data.compatible_table().matches(&PLATFORM_COMPAT_TABLE) {
return Ok(());
} else {
return Err(DriverError::UnsupportedOperation);
}
/// 检测设备是否能绑定到这个驱动
///
/// 如果能则把设备的driver指向这个驱动。
/// 请注意这个函数不应该把driver加入驱动的devices列表相关工作会在外部的函数里面处理。
fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
fn remove(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
fn shutdown(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
fn suspend(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
fn resume(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
}
#[inline(always)]
pub fn platform_driver_manager() -> &'static PlatformDriverManager {
&PlatformDriverManager
}
#[derive(Debug)]
pub struct PlatformDriverManager;
impl PlatformDriverManager {
/// 注册平台设备驱动
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=__platform_driver_register#861
pub fn register(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), SystemError> {
driver.set_bus(Some(platform_bus() as Arc<dyn Bus>));
return driver_manager().register(driver as Arc<dyn Driver>);
}
/// 卸载平台设备驱动
#[allow(dead_code)]
pub fn unregister(&self, driver: &Arc<dyn PlatformDriver>) {
driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
}
}

View File

@ -2,15 +2,26 @@ use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
};
use intertrait::cast::CastArc;
use crate::{
driver::base::{device::bus::Bus, kobject::KObject, subsys::SubSysPrivate},
driver::{
acpi::acpi_manager,
base::{
device::{bus::Bus, driver::Driver, Device},
kobject::KObject,
subsys::SubSysPrivate,
},
},
filesystem::{
sysfs::{Attribute, AttributeGroup},
vfs::syscall::ModeType,
},
syscall::SystemError,
};
use super::{platform_device::PlatformDevice, platform_driver::PlatformDriver};
#[derive(Debug)]
pub struct PlatformBus {
private: SubSysPrivate,
@ -44,6 +55,92 @@ impl Bus for PlatformBus {
fn subsystem(&self) -> &SubSysPrivate {
return &self.private;
}
fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
let drv = device.driver().ok_or(SystemError::EINVAL)?;
let pdrv = drv.cast::<dyn PlatformDriver>().map_err(|_|{
kerror!("PlatformBus::probe() failed: device.driver() is not a PlatformDriver. Device: '{:?}'", device.name());
SystemError::EINVAL
})?;
let pdev = device.clone().cast::<dyn PlatformDevice>().map_err(|_| {
kerror!(
"PlatformBus::probe() failed: device is not a PlatformDevice. Device: '{:?}'",
device.name()
);
SystemError::EINVAL
})?;
return pdrv.probe(&pdev);
}
fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
todo!()
}
fn sync_state(&self, _device: &Arc<dyn Device>) {
todo!()
}
fn shutdown(&self, _device: &Arc<dyn Device>) {
todo!()
}
fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
todo!()
}
///
/// match platform device to platform driver.
///
/// ## 参数
///
/// * `device` - platform device
/// * `driver` - platform driver
///
/// ## 返回
///
/// - `Ok(true)` - 匹配成功
/// - `Ok(false)` - 匹配失败
/// - `Err(_)` - 由于内部错误导致匹配失败
///
/// Platform device IDs are assumed to be encoded like this:
/// "<name><instance>", where <name> is a short description of the type of
/// device, like "pci" or "floppy", and <instance> is the enumerated
/// instance of the device, like '0' or '42'. Driver IDs are simply
/// "<name>". So, extract the <name> from the platform_device structure,
/// and compare it against the name of the driver. Return whether they match
/// or not.
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c#1331
///
///
fn match_device(
&self,
device: &Arc<dyn Device>,
driver: &Arc<dyn Driver>,
) -> Result<bool, SystemError> {
// 尝试从 ACPI 中匹配
if let Ok(x) = acpi_manager().driver_match_device(driver, device) {
if x {
return Ok(true);
}
}
// 尝试从 ID table 中匹配
if let Some(drv_id_table) = driver.id_table() {
let pdev = device
.clone()
.cast::<dyn PlatformDevice>()
.map_err(|_| SystemError::EINVAL)?;
if drv_id_table.name().eq(&pdev.name()) {
return Ok(true);
}
}
// 尝试根据设备名称匹配
return Ok(device.name().eq(&driver.name()));
}
}
#[derive(Debug)]