1 use alloc::{
2 string::ToString,
3 sync::{Arc, Weak},
4 };
5 use system_error::SystemError;
6 use unified_init::macros::unified_init;
7
8 use crate::{
9 driver::base::{
10 class::{class_manager, Class},
11 device::sys_dev_char_kset,
12 kobject::KObject,
13 subsys::SubSysPrivate,
14 },
15 init::initcall::INITCALL_SUBSYS,
16 };
17
18 /// `/sys/class/tty` 的 class 实例
19 static mut CLASS_TTY_INSTANCE: Option<Arc<TtyClass>> = None;
20
21 /// 获取 `/sys/class/tty` 的 class 实例
22 #[inline(always)]
23 #[allow(dead_code)]
sys_class_tty_instance() -> Option<&'static Arc<TtyClass>>24 pub fn sys_class_tty_instance() -> Option<&'static Arc<TtyClass>> {
25 unsafe { CLASS_TTY_INSTANCE.as_ref() }
26 }
27
28 /// `/sys/class/tty` 类
29 #[derive(Debug)]
30 pub struct TtyClass {
31 subsystem: SubSysPrivate,
32 }
33
34 impl TtyClass {
35 const NAME: &'static str = "tty";
new() -> Arc<Self>36 pub fn new() -> Arc<Self> {
37 let r = Self {
38 subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
39 };
40 let r = Arc::new(r);
41 r.subsystem()
42 .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>));
43
44 return r;
45 }
46 }
47
48 impl Class for TtyClass {
name(&self) -> &'static str49 fn name(&self) -> &'static str {
50 return Self::NAME;
51 }
52
dev_kobj(&self) -> Option<Arc<dyn KObject>>53 fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
54 Some(sys_dev_char_kset() as Arc<dyn KObject>)
55 }
56
set_dev_kobj(&self, _kobj: Arc<dyn KObject>)57 fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
58 unimplemented!("TtyClass::set_dev_kobj");
59 }
60
subsystem(&self) -> &SubSysPrivate61 fn subsystem(&self) -> &SubSysPrivate {
62 return &self.subsystem;
63 }
64 }
65
66 /// 初始化帧缓冲区子系统
67 #[unified_init(INITCALL_SUBSYS)]
tty_sysfs_init() -> Result<(), SystemError>68 pub fn tty_sysfs_init() -> Result<(), SystemError> {
69 let tty_class = TtyClass::new();
70 class_manager().class_register(&(tty_class.clone() as Arc<dyn Class>))?;
71
72 unsafe {
73 CLASS_TTY_INSTANCE = Some(tty_class);
74 }
75
76 return Ok(());
77 }
78