Skip to content

Commit 4360822

Browse files
fslongjinyuyi2439
authored andcommitted
bugfix: bus/device manager对卸载逻辑的处理错误 (DragonOS-Community#385)
* 移动位置 * bugfix: bus/device manager对卸载逻辑的处理错误
1 parent d342011 commit 4360822

File tree

7 files changed

+428
-392
lines changed

7 files changed

+428
-392
lines changed

kernel/src/driver/base/block/block_device.rs

Lines changed: 185 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
/// 引入Module
2-
use crate::{driver::base::device::Device, syscall::SystemError};
2+
use crate::{
3+
driver::base::{
4+
device::{mkdev, Device, DeviceNumber, IdTable, BLOCKDEVS, DEVICE_MANAGER},
5+
map::{
6+
DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
7+
DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
8+
},
9+
},
10+
kerror,
11+
syscall::SystemError,
12+
};
313
use alloc::{sync::Arc, vec::Vec};
414
use core::any::Any;
515

@@ -307,3 +317,177 @@ pub trait BlockDevice: Device {
307317
// );
308318
}
309319
}
320+
321+
/// @brief 块设备框架函数集
322+
pub struct BlockDeviceOps;
323+
324+
impl BlockDeviceOps {
325+
/// @brief: 主设备号转下标
326+
/// @parameter: major: 主设备号
327+
/// @return: 返回下标
328+
#[allow(dead_code)]
329+
fn major_to_index(major: usize) -> usize {
330+
return major % DEV_MAJOR_HASH_SIZE;
331+
}
332+
333+
/// @brief: 动态获取主设备号
334+
/// @parameter: None
335+
/// @return: 如果成功,返回主设备号,否则,返回错误码
336+
#[allow(dead_code)]
337+
fn find_dynamic_major() -> Result<usize, SystemError> {
338+
let blockdevs = BLOCKDEVS.lock();
339+
// 寻找主设备号为234~255的设备
340+
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
341+
if let Some(item) = blockdevs.get(index) {
342+
if item.is_empty() {
343+
return Ok(index); // 返回可用的主设备号
344+
}
345+
}
346+
}
347+
// 寻找主设备号在384~511的设备
348+
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
349+
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(index)) {
350+
let mut flag = true;
351+
for item in blockdevss {
352+
if item.device_number().major() == index {
353+
flag = false;
354+
break;
355+
}
356+
}
357+
if flag {
358+
// 如果数组中不存在主设备号等于index的设备
359+
return Ok(index); // 返回可用的主设备号
360+
}
361+
}
362+
}
363+
return Err(SystemError::EBUSY);
364+
}
365+
366+
/// @brief: 注册设备号,该函数需要指定主设备号
367+
/// @parameter: from: 主设备号
368+
/// count: 次设备号数量
369+
/// name: 字符设备名
370+
/// @return: 如果注册成功,返回设备号,否则,返回错误码
371+
#[allow(dead_code)]
372+
pub fn register_blockdev_region(
373+
from: DeviceNumber,
374+
count: usize,
375+
name: &'static str,
376+
) -> Result<DeviceNumber, SystemError> {
377+
Self::__register_blockdev_region(from, count, name)
378+
}
379+
380+
/// @brief: 注册设备号,该函数自动分配主设备号
381+
/// @parameter: baseminor: 主设备号
382+
/// count: 次设备号数量
383+
/// name: 字符设备名
384+
/// @return: 如果注册成功,返回,否则,返回false
385+
#[allow(dead_code)]
386+
pub fn alloc_blockdev_region(
387+
baseminor: usize,
388+
count: usize,
389+
name: &'static str,
390+
) -> Result<DeviceNumber, SystemError> {
391+
Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
392+
}
393+
394+
/// @brief: 注册设备号
395+
/// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
396+
/// minorct: 次设备号数量
397+
/// name: 字符设备名
398+
/// @return: 如果注册成功,返回设备号,否则,返回错误码
399+
fn __register_blockdev_region(
400+
device_number: DeviceNumber,
401+
minorct: usize,
402+
name: &'static str,
403+
) -> Result<DeviceNumber, SystemError> {
404+
let mut major = device_number.major();
405+
let baseminor = device_number.minor();
406+
if major >= DEV_MAJOR_MAX {
407+
kerror!(
408+
"DEV {} major requested {} is greater than the maximum {}\n",
409+
name,
410+
major,
411+
DEV_MAJOR_MAX - 1
412+
);
413+
}
414+
if minorct > MINOR_MASK + 1 - baseminor {
415+
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
416+
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
417+
}
418+
let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
419+
if major == 0 {
420+
// 如果主设备号为0,则自动分配主设备号
421+
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
422+
}
423+
if let Some(items) = BLOCKDEVS.lock().get_mut(Self::major_to_index(major)) {
424+
let mut insert_index: usize = 0;
425+
for (index, item) in items.iter().enumerate() {
426+
insert_index = index;
427+
match item.device_number().major().cmp(&major) {
428+
core::cmp::Ordering::Less => continue,
429+
core::cmp::Ordering::Greater => {
430+
break; // 大于则向后插入
431+
}
432+
core::cmp::Ordering::Equal => {
433+
if item.device_number().minor() + item.minorct() <= baseminor {
434+
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
435+
}
436+
if item.base_minor() >= baseminor + minorct {
437+
break; // 在此处插入
438+
}
439+
return Err(SystemError::EBUSY); // 存在重合的次设备号
440+
}
441+
}
442+
}
443+
items.insert(insert_index, blockdev);
444+
}
445+
return Ok(mkdev(major, baseminor));
446+
}
447+
448+
/// @brief: 注销设备号
449+
/// @parameter: major: 主设备号,如果为0,动态分配
450+
/// baseminor: 起始次设备号
451+
/// minorct: 次设备号数量
452+
/// @return: 如果注销成功,返回(),否则,返回错误码
453+
fn __unregister_blockdev_region(
454+
device_number: DeviceNumber,
455+
minorct: usize,
456+
) -> Result<(), SystemError> {
457+
if let Some(items) = BLOCKDEVS
458+
.lock()
459+
.get_mut(Self::major_to_index(device_number.major()))
460+
{
461+
for (index, item) in items.iter().enumerate() {
462+
if item.device_number() == device_number && item.minorct() == minorct {
463+
// 设备号和数量都相等
464+
items.remove(index);
465+
return Ok(());
466+
}
467+
}
468+
}
469+
return Err(SystemError::EBUSY);
470+
}
471+
472+
/// @brief: 块设备注册
473+
/// @parameter: cdev: 字符设备实例
474+
/// dev_t: 字符设备号
475+
/// range: 次设备号范围
476+
/// @return: none
477+
#[allow(dead_code)]
478+
pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) {
479+
if Into::<usize>::into(id_table.device_number()) == 0 {
480+
kerror!("Device number can't be 0!\n");
481+
}
482+
DEVICE_MANAGER.add_device(id_table, bdev.device())
483+
}
484+
485+
/// @brief: block设备注销
486+
/// @parameter: dev_t: 字符设备号
487+
/// range: 次设备号范围
488+
/// @return: none
489+
#[allow(dead_code)]
490+
pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {
491+
unimplemented!();
492+
}
493+
}

kernel/src/driver/base/char/mod.rs

Lines changed: 191 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
use crate::syscall::SystemError;
1+
use alloc::sync::Arc;
22

3-
use super::device::Device;
3+
use crate::{kerror, syscall::SystemError};
4+
5+
use super::{
6+
device::{mkdev, Device, DeviceNumber, IdTable, CHARDEVS, DEVICE_MANAGER, DEVMAP},
7+
map::{
8+
kobj_map, kobj_unmap, DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END,
9+
DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
10+
},
11+
};
412

513
pub trait CharDevice: Device {
614
/// Notice buffer对应设备按字节划分,使用u8类型
@@ -23,3 +31,184 @@ pub trait CharDevice: Device {
2331
/// @brief: 同步信息,把所有的dirty数据写回设备 - 待实现
2432
fn sync(&self) -> Result<(), SystemError>;
2533
}
34+
35+
/// @brief 字符设备框架函数集
36+
pub struct CharDevOps;
37+
38+
impl CharDevOps {
39+
/// @brief: 主设备号转下标
40+
/// @parameter: major: 主设备号
41+
/// @return: 返回下标
42+
#[allow(dead_code)]
43+
fn major_to_index(major: usize) -> usize {
44+
return major % DEV_MAJOR_HASH_SIZE;
45+
}
46+
47+
/// @brief: 动态获取主设备号
48+
/// @parameter: None
49+
/// @return: 如果成功,返回主设备号,否则,返回错误码
50+
#[allow(dead_code)]
51+
fn find_dynamic_major() -> Result<usize, SystemError> {
52+
let chardevs = CHARDEVS.lock();
53+
// 寻找主设备号为234~255的设备
54+
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
55+
if let Some(item) = chardevs.get(index) {
56+
if item.is_empty() {
57+
return Ok(index); // 返回可用的主设备号
58+
}
59+
}
60+
}
61+
// 寻找主设备号在384~511的设备
62+
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
63+
if let Some(chardevss) = chardevs.get(Self::major_to_index(index)) {
64+
let mut flag = true;
65+
for item in chardevss {
66+
if item.device_number().major() == index {
67+
flag = false;
68+
break;
69+
}
70+
}
71+
if flag {
72+
// 如果数组中不存在主设备号等于index的设备
73+
return Ok(index); // 返回可用的主设备号
74+
}
75+
}
76+
}
77+
return Err(SystemError::EBUSY);
78+
}
79+
80+
/// @brief: 注册设备号,该函数需要指定主设备号
81+
/// @parameter: from: 主设备号
82+
/// count: 次设备号数量
83+
/// name: 字符设备名
84+
/// @return: 如果注册成功,返回设备号,否则,返回错误码
85+
#[allow(dead_code)]
86+
pub fn register_chardev_region(
87+
from: DeviceNumber,
88+
count: usize,
89+
name: &'static str,
90+
) -> Result<DeviceNumber, SystemError> {
91+
Self::__register_chardev_region(from, count, name)
92+
}
93+
94+
/// @brief: 注册设备号,该函数自动分配主设备号
95+
/// @parameter: baseminor: 次设备号
96+
/// count: 次设备号数量
97+
/// name: 字符设备名
98+
/// @return: 如果注册成功,返回,否则,返回false
99+
#[allow(dead_code)]
100+
pub fn alloc_chardev_region(
101+
baseminor: usize,
102+
count: usize,
103+
name: &'static str,
104+
) -> Result<DeviceNumber, SystemError> {
105+
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
106+
}
107+
108+
/// @brief: 注册设备号
109+
/// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
110+
/// minorct: 次设备号数量
111+
/// name: 字符设备名
112+
/// @return: 如果注册成功,返回设备号,否则,返回错误码
113+
fn __register_chardev_region(
114+
device_number: DeviceNumber,
115+
minorct: usize,
116+
name: &'static str,
117+
) -> Result<DeviceNumber, SystemError> {
118+
let mut major = device_number.major();
119+
let baseminor = device_number.minor();
120+
if major >= DEV_MAJOR_MAX {
121+
kerror!(
122+
"DEV {} major requested {} is greater than the maximum {}\n",
123+
name,
124+
major,
125+
DEV_MAJOR_MAX - 1
126+
);
127+
}
128+
if minorct > MINOR_MASK + 1 - baseminor {
129+
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
130+
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
131+
}
132+
let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
133+
if major == 0 {
134+
// 如果主设备号为0,则自动分配主设备号
135+
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
136+
}
137+
if let Some(items) = CHARDEVS.lock().get_mut(Self::major_to_index(major)) {
138+
let mut insert_index: usize = 0;
139+
for (index, item) in items.iter().enumerate() {
140+
insert_index = index;
141+
match item.device_number().major().cmp(&major) {
142+
core::cmp::Ordering::Less => continue,
143+
core::cmp::Ordering::Greater => {
144+
break; // 大于则向后插入
145+
}
146+
core::cmp::Ordering::Equal => {
147+
if item.device_number().minor() + item.minorct() <= baseminor {
148+
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
149+
}
150+
if item.base_minor() >= baseminor + minorct {
151+
break; // 在此处插入
152+
}
153+
return Err(SystemError::EBUSY); // 存在重合的次设备号
154+
}
155+
}
156+
}
157+
items.insert(insert_index, chardev);
158+
}
159+
return Ok(mkdev(major, baseminor));
160+
}
161+
162+
/// @brief: 注销设备号
163+
/// @parameter: major: 主设备号,如果为0,动态分配
164+
/// baseminor: 起始次设备号
165+
/// minorct: 次设备号数量
166+
/// @return: 如果注销成功,返回(),否则,返回错误码
167+
fn __unregister_chardev_region(
168+
device_number: DeviceNumber,
169+
minorct: usize,
170+
) -> Result<(), SystemError> {
171+
if let Some(items) = CHARDEVS
172+
.lock()
173+
.get_mut(Self::major_to_index(device_number.major()))
174+
{
175+
for (index, item) in items.iter().enumerate() {
176+
if item.device_number() == device_number && item.minorct() == minorct {
177+
// 设备号和数量都相等
178+
items.remove(index);
179+
return Ok(());
180+
}
181+
}
182+
}
183+
return Err(SystemError::EBUSY);
184+
}
185+
186+
/// @brief: 字符设备注册
187+
/// @parameter: cdev: 字符设备实例
188+
/// dev_t: 字符设备号
189+
/// range: 次设备号范围
190+
/// @return: none
191+
#[allow(dead_code)]
192+
pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) {
193+
if Into::<usize>::into(id_table.device_number()) == 0 {
194+
kerror!("Device number can't be 0!\n");
195+
}
196+
DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone());
197+
kobj_map(
198+
DEVMAP.clone(),
199+
id_table.device_number(),
200+
range,
201+
cdev.clone(),
202+
)
203+
}
204+
205+
/// @brief: 字符设备注销
206+
/// @parameter: dev_t: 字符设备号
207+
/// range: 次设备号范围
208+
/// @return: none
209+
#[allow(dead_code)]
210+
pub fn cdev_del(id_table: IdTable, range: usize) {
211+
DEVICE_MANAGER.remove_device(&id_table);
212+
kobj_unmap(DEVMAP.clone(), id_table.device_number(), range);
213+
}
214+
}

0 commit comments

Comments
 (0)