bugfix: bus/device manager对卸载逻辑的处理错误 (#385)

* 移动位置

* bugfix: bus/device manager对卸载逻辑的处理错误
This commit is contained in:
LoGin
2023-09-18 07:38:04 +08:00
committed by GitHub
parent 7ae679ddd6
commit ae5ede03be
7 changed files with 428 additions and 392 deletions

View File

@ -1,5 +1,15 @@
/// 引入Module
use crate::{driver::base::device::Device, syscall::SystemError};
use crate::{
driver::base::{
device::{mkdev, Device, DeviceNumber, IdTable, BLOCKDEVS, DEVICE_MANAGER},
map::{
DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
},
},
kerror,
syscall::SystemError,
};
use alloc::{sync::Arc, vec::Vec};
use core::any::Any;
@ -307,3 +317,177 @@ pub trait BlockDevice: Device {
// );
}
}
/// @brief 块设备框架函数集
pub struct BlockDeviceOps;
impl BlockDeviceOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let blockdevs = BLOCKDEVS.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = blockdevs.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(index)) {
let mut flag = true;
for item in blockdevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_blockdev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_blockdev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = BLOCKDEVS.lock().get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
core::cmp::Ordering::Less => continue,
core::cmp::Ordering::Greater => {
break; // 大于则向后插入
}
core::cmp::Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, blockdev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = BLOCKDEVS
.lock()
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 块设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) {
if Into::<usize>::into(id_table.device_number()) == 0 {
kerror!("Device number can't be 0!\n");
}
DEVICE_MANAGER.add_device(id_table, bdev.device())
}
/// @brief: block设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {
unimplemented!();
}
}

View File

@ -1,6 +1,14 @@
use crate::syscall::SystemError;
use alloc::sync::Arc;
use super::device::Device;
use crate::{kerror, syscall::SystemError};
use super::{
device::{mkdev, Device, DeviceNumber, IdTable, CHARDEVS, DEVICE_MANAGER, DEVMAP},
map::{
kobj_map, kobj_unmap, DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END,
DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
},
};
pub trait CharDevice: Device {
/// Notice buffer对应设备按字节划分使用u8类型
@ -23,3 +31,184 @@ pub trait CharDevice: Device {
/// @brief: 同步信息把所有的dirty数据写回设备 - 待实现
fn sync(&self) -> Result<(), SystemError>;
}
/// @brief 字符设备框架函数集
pub struct CharDevOps;
impl CharDevOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let chardevs = CHARDEVS.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(chardevss) = chardevs.get(Self::major_to_index(index)) {
let mut flag = true;
for item in chardevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_chardev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 次设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_chardev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_chardev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = CHARDEVS.lock().get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
core::cmp::Ordering::Less => continue,
core::cmp::Ordering::Greater => {
break; // 大于则向后插入
}
core::cmp::Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, chardev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_chardev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = CHARDEVS
.lock()
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 字符设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) {
if Into::<usize>::into(id_table.device_number()) == 0 {
kerror!("Device number can't be 0!\n");
}
DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone());
kobj_map(
DEVMAP.clone(),
id_table.device_number(),
range,
cdev.clone(),
)
}
/// @brief: 字符设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_del(id_table: IdTable, range: usize) {
DEVICE_MANAGER.remove_device(&id_table);
kobj_unmap(DEVMAP.clone(), id_table.device_number(), range);
}
}

View File

@ -191,7 +191,7 @@ pub fn bus_register<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_unregister<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
BUS_MANAGER.add_bus(bus.id_table(), bus.clone());
BUS_MANAGER.remove_bus(&bus.id_table());
return device_unregister(bus);
}
@ -208,6 +208,6 @@ pub fn bus_driver_register(bus_driver: Arc<dyn BusDriver>) -> Result<(), DriverE
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_driver_unregister(bus_driver: Arc<dyn BusDriver>) -> Result<(), DriverError> {
BUS_MANAGER.add_driver(bus_driver.id_table(), bus_driver.clone());
BUS_MANAGER.remove_bus_driver(&bus_driver.id_table());
return driver_unregister(bus_driver);
}

View File

@ -119,6 +119,6 @@ pub fn driver_register(driver: Arc<dyn Driver>) -> Result<(), DriverError> {
/// @return: 操作成功,返回(),操作失败,返回错误码
#[allow(dead_code)]
pub fn driver_unregister(driver: Arc<dyn Driver>) -> Result<(), DriverError> {
DRIVER_MANAGER.add_driver(driver.id_table(), driver);
DRIVER_MANAGER.remove_driver(&driver.id_table());
return Ok(());
}

View File

@ -1,23 +1,19 @@
use core::cmp::Ordering;
use core::ops::{Deref, DerefMut};
use super::{
block::block_device::BlockDevice,
char::CharDevice,
device::{mkdev, DeviceNumber, IdTable, KObject, BLOCKDEVS, CHARDEVS, DEVICE_MANAGER, DEVMAP},
};
use crate::{kerror, libs::spinlock::SpinLock, syscall::SystemError};
use super::device::{mkdev, DeviceNumber, KObject};
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
const KOBJMAP_HASH_SIZE: usize = 255;
const DEV_MAJOR_HASH_SIZE: usize = 255;
const DEV_MAJOR_MAX: usize = 512;
const MINOR_BITS: usize = 20;
const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
pub(crate) const DEV_MAJOR_HASH_SIZE: usize = 255;
pub(crate) const DEV_MAJOR_MAX: usize = 512;
pub(crate) const MINOR_BITS: usize = 20;
pub(crate) const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
/* Marks the bottom of the first segment of free char majors */
const DEV_MAJOR_DYN_END: usize = 234;
pub(crate) const DEV_MAJOR_DYN_END: usize = 234;
/* Marks the top and bottom of the second segment of free char majors */
const DEV_MAJOR_DYN_EXT_START: usize = 511;
const DEV_MAJOR_DYN_EXT_END: usize = 384;
pub(crate) const DEV_MAJOR_DYN_EXT_START: usize = 511;
pub(crate) const DEV_MAJOR_DYN_EXT_END: usize = 384;
/// @brief: 字符设备与块设备管理结构体
#[derive(Debug, Clone)]
@ -121,9 +117,16 @@ impl Default for LockedDevsMap {
}
}
impl LockedDevsMap {
#[inline(always)]
pub fn lock(&self) -> SpinLockGuard<DevsMap> {
self.0.lock()
}
}
// 管理字符设备号的map
#[derive(Debug)]
struct DevsMap(Vec<Vec<DeviceStruct>>);
pub struct DevsMap(Vec<Vec<DeviceStruct>>);
impl Default for DevsMap {
fn default() -> Self {
@ -131,6 +134,20 @@ impl Default for DevsMap {
}
}
impl Deref for DevsMap {
type Target = Vec<Vec<DeviceStruct>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for DevsMap {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
// 字符设备在系统中的实例devfs通过该结构与实际字符设备进行联系
#[allow(dead_code)]
#[derive(Debug, Clone)]
@ -183,363 +200,3 @@ impl DeviceStruct {
self.minorct
}
}
// 这下面是考虑到 块设备的注册和字符设备的注册在设备号的自动分配上要有所区别,
// 暂时没有去查具体是怎么做区分的,因此暂时还是一样的
/// @brief 块设备框架函数集
pub struct BlockDeviceOps;
impl BlockDeviceOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let blockdevs = BLOCKDEVS.0.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = blockdevs.0.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(blockdevss) = blockdevs.0.get(Self::major_to_index(index)) {
let mut flag = true;
for item in blockdevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_blockdev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_blockdev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = BLOCKDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
Ordering::Less => continue,
Ordering::Greater => {
break; // 大于则向后插入
}
Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, blockdev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = BLOCKDEVS
.0
.lock()
.0
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 块设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) {
if Into::<usize>::into(id_table.device_number()) == 0 {
kerror!("Device number can't be 0!\n");
}
DEVICE_MANAGER.add_device(id_table, bdev.device())
}
/// @brief: block设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {}
}
/// @brief 字符设备框架函数集
pub struct CharDevOps;
impl CharDevOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let chardevs = CHARDEVS.0.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.0.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) {
let mut flag = true;
for item in chardevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_chardev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 次设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_chardev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_chardev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
Ordering::Less => continue,
Ordering::Greater => {
break; // 大于则向后插入
}
Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, chardev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_chardev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = CHARDEVS
.0
.lock()
.0
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 字符设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) {
if Into::<usize>::into(id_table.device_number()) == 0 {
kerror!("Device number can't be 0!\n");
}
DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone());
kobj_map(
DEVMAP.clone(),
id_table.device_number(),
range,
cdev.clone(),
)
}
/// @brief: 字符设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_del(id_table: IdTable, range: usize) {
DEVICE_MANAGER.remove_device(&id_table);
kobj_unmap(DEVMAP.clone(), id_table.device_number(), range);
}
}

View File

@ -1,7 +1,7 @@
use alloc::sync::Arc;
use crate::driver::base::char::CharDevOps;
use crate::driver::base::device::{Device, DeviceResource, DEVICE_MANAGER};
use crate::driver::base::map::CharDevOps;
use crate::driver::base::platform::CompatibleTable;
use crate::{
driver::{

View File

@ -14,13 +14,11 @@ use crate::{
time::TimeSpec,
};
use alloc::{
boxed::Box,
collections::BTreeMap,
string::{String, ToString},
sync::{Arc, Weak},
vec::Vec,
};
use core::ptr::null_mut;
pub mod bus;
pub mod class;
@ -29,10 +27,10 @@ pub mod fs;
const SYSFS_MAX_NAMELEN: usize = 64;
static mut __SYS_DEVICES_INODE: *mut Arc<dyn IndexNode> = null_mut();
static mut __SYS_BUS_INODE: *mut Arc<dyn IndexNode> = null_mut();
static mut __SYS_CLASS_INODE: *mut Arc<dyn IndexNode> = null_mut();
static mut __SYS_FS_INODE: *mut Arc<dyn IndexNode> = null_mut();
static mut __SYS_DEVICES_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_BUS_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_CLASS_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_FS_INODE: Option<Arc<dyn IndexNode>> = None;
/// @brief 获取全局的sys/devices节点
#[inline(always)]
@ -117,28 +115,28 @@ impl SysFS {
let root: &Arc<LockedSysFSInode> = &sysfs.root_inode;
match root.add_dir("devices") {
Ok(devices) => unsafe {
__SYS_DEVICES_INODE = Box::leak(Box::new(devices));
__SYS_DEVICES_INODE = Some(devices);
},
Err(_) => panic!("SysFS: Failed to create /sys/devices"),
}
match root.add_dir("bus") {
Ok(bus) => unsafe {
__SYS_BUS_INODE = Box::leak(Box::new(bus));
__SYS_BUS_INODE = Some(bus);
},
Err(_) => panic!("SysFS: Failed to create /sys/bus"),
}
match root.add_dir("class") {
Ok(class) => unsafe {
__SYS_CLASS_INODE = Box::leak(Box::new(class));
__SYS_CLASS_INODE = Some(class);
},
Err(_) => panic!("SysFS: Failed to create /sys/class"),
}
match root.add_dir("fs") {
Ok(fs) => unsafe {
__SYS_FS_INODE = Box::leak(Box::new(fs));
__SYS_FS_INODE = Some(fs);
},
Err(_) => panic!("SysFS: Failed to create /sys/fs"),
}
@ -156,6 +154,14 @@ impl IndexNode for LockedSysFSInode {
self
}
fn resize(&self, _len: usize) -> Result<(), SystemError> {
return Ok(());
}
fn truncate(&self, _len: usize) -> Result<(), SystemError> {
return Ok(());
}
fn open(
&self,
_data: &mut super::vfs::FilePrivateData,