xref: /DragonOS/kernel/src/driver/tty/tty_driver.rs (revision 9fab312ea9921618629924ab15c28c2d255b21c6)
1 use core::fmt::Debug;
2 
3 use alloc::{
4     string::{String, ToString},
5     sync::{Arc, Weak},
6     vec::Vec,
7 };
8 use hashbrown::HashMap;
9 use system_error::SystemError;
10 
11 use crate::{
12     driver::{
13         base::{
14             char::CharDevOps,
15             device::{
16                 device_number::{DeviceNumber, Major},
17                 driver::Driver,
18             },
19             kobject::KObject,
20         },
21         tty::tty_port::TtyPortState,
22     },
23     libs::{
24         rwlock::RwLock,
25         spinlock::{SpinLock, SpinLockGuard},
26     },
27 };
28 
29 use super::{
30     termios::{Termios, WindowSize},
31     tty_core::{TtyCore, TtyCoreData},
32     tty_ldisc::TtyLdiscManager,
33     tty_port::{DefaultTtyPort, TtyPort},
34 };
35 
36 lazy_static! {
37     pub static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
38 }
39 
40 pub enum TtyDriverPrivateData {
41     Unused,
42     /// true表示主设备 false表示从设备
43     Pty(bool),
44 }
45 
46 pub struct TtyDriverManager;
47 impl TtyDriverManager {
48     pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
49         let drivers_guard = TTY_DRIVERS.lock();
50         for driver in drivers_guard.iter() {
51             let base = DeviceNumber::new(driver.major, driver.minor_start);
52             if dev_num < base || dev_num.data() > base.data() + driver.device_count {
53                 continue;
54             }
55             return Some(((dev_num.data() - base.data()) as usize, driver.clone()));
56         }
57 
58         None
59     }
60 
61     /// ## 注册驱动
62     pub fn tty_register_driver(mut driver: TtyDriver) -> Result<Arc<TtyDriver>, SystemError> {
63         // 查看是否注册设备号
64         if driver.major == Major::UNNAMED_MAJOR {
65             let dev_num = CharDevOps::alloc_chardev_region(
66                 driver.minor_start,
67                 driver.device_count,
68                 driver.name,
69             )?;
70             driver.major = dev_num.major();
71             driver.minor_start = dev_num.minor();
72         } else {
73             let dev_num = DeviceNumber::new(driver.major, driver.minor_start);
74             CharDevOps::register_chardev_region(dev_num, driver.device_count, driver.name)?;
75         }
76 
77         driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
78 
79         // 加入全局TtyDriver表
80         let driver = Arc::new(driver);
81         TTY_DRIVERS.lock().push(driver.clone());
82 
83         // TODO: 加入procfs?
84 
85         Ok(driver)
86     }
87 }
88 
89 #[allow(dead_code)]
90 #[derive(Debug)]
91 #[cast_to([sync] Driver)]
92 pub struct TtyDriver {
93     /// /proc/tty中使用的驱动程序名称
94     driver_name: String,
95     /// 用于构造/dev节点名称,例如name设置为tty,则按照name_base分配节点tty0,tty1等
96     name: &'static str,
97     /// 命名基数
98     name_base: usize,
99     /// 主设备号
100     major: Major,
101     /// 起始次设备号
102     minor_start: u32,
103     /// 最多支持的tty数量
104     device_count: u32,
105     /// tty驱动程序类型
106     tty_driver_type: TtyDriverType,
107     /// 驱动程序子类型
108     tty_driver_sub_type: TtyDriverSubType,
109     /// 每个tty的默认termios
110     init_termios: Termios,
111     /// 懒加载termios,在tty设备关闭时,会将termios按照设备的index保存进这个集合,以便下次打开使用
112     saved_termios: Vec<Termios>,
113     /// 驱动程序标志
114     flags: TtyDriverFlag,
115     /// pty链接此driver的入口
116     other_pty_driver: RwLock<Weak<TtyDriver>>,
117     /// 具体类型的tty驱动方法
118     driver_funcs: Arc<dyn TtyOperation>,
119     /// 管理的tty设备列表
120     ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
121     /// 管理的端口列表
122     ports: RwLock<Vec<Arc<dyn TtyPort>>>,
123     // procfs入口?
124 }
125 
126 impl TtyDriver {
127     #[allow(clippy::too_many_arguments)]
128     pub fn new(
129         count: u32,
130         node_name: &'static str,
131         node_name_base: usize,
132         major: Major,
133         minor_start: u32,
134         tty_driver_type: TtyDriverType,
135         default_termios: Termios,
136         driver_funcs: Arc<dyn TtyOperation>,
137     ) -> Self {
138         let mut ports: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(count as usize);
139         for _ in 0..count {
140             ports.push(Arc::new(DefaultTtyPort::new()))
141         }
142         TtyDriver {
143             driver_name: Default::default(),
144             name: node_name,
145             name_base: node_name_base,
146             major,
147             minor_start,
148             device_count: count,
149             tty_driver_type,
150             tty_driver_sub_type: Default::default(),
151             init_termios: default_termios,
152             flags: TtyDriverFlag::empty(),
153             other_pty_driver: Default::default(),
154             driver_funcs,
155             ttys: SpinLock::new(HashMap::new()),
156             saved_termios: Vec::with_capacity(count as usize),
157             ports: RwLock::new(ports),
158         }
159     }
160 
161     pub fn tty_line_name(&self, index: usize) -> String {
162         if self
163             .flags
164             .contains(TtyDriverFlag::TTY_DRIVER_UNNUMBERED_NODE)
165         {
166             return self.name.to_string();
167         } else {
168             return format!("{}{}", self.name, index + self.name_base);
169         }
170     }
171 
172     pub fn add_tty(&self, tty_core: Arc<TtyCore>) {
173         self.ttys.lock().insert(tty_core.core().index(), tty_core);
174     }
175 
176     #[inline]
177     pub fn driver_funcs(&self) -> Arc<dyn TtyOperation> {
178         self.driver_funcs.clone()
179     }
180 
181     #[inline]
182     pub fn init_termios(&self) -> Termios {
183         self.init_termios
184     }
185 
186     #[inline]
187     pub fn init_termios_mut(&mut self) -> &mut Termios {
188         &mut self.init_termios
189     }
190 
191     #[inline]
192     pub fn other_pty_driver(&self) -> Option<Arc<TtyDriver>> {
193         self.other_pty_driver.read().upgrade()
194     }
195 
196     pub fn set_other_pty_driver(&self, driver: Weak<TtyDriver>) {
197         *self.other_pty_driver.write() = driver
198     }
199 
200     #[inline]
201     pub fn set_subtype(&mut self, tp: TtyDriverSubType) {
202         self.tty_driver_sub_type = tp;
203     }
204 
205     #[inline]
206     pub fn ttys(&self) -> SpinLockGuard<HashMap<usize, Arc<TtyCore>>> {
207         self.ttys.lock()
208     }
209 
210     #[inline]
211     pub fn saved_termios(&self) -> &Vec<Termios> {
212         &self.saved_termios
213     }
214 
215     #[inline]
216     pub fn flags(&self) -> TtyDriverFlag {
217         self.flags
218     }
219 
220     #[inline]
221     fn lookup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
222         let ret = self
223             .driver_funcs()
224             .lookup(index, TtyDriverPrivateData::Unused);
225         if let Err(SystemError::ENOSYS) = ret {
226             let device_guard = self.ttys.lock();
227             return device_guard.get(&index).cloned();
228         }
229         ret.ok()
230     }
231 
232     fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
233         let tty = tty_core.core();
234         tty.init_termios();
235         // TODO:设置termios波特率?
236 
237         tty.add_count();
238 
239         self.ttys.lock().insert(tty.index(), tty_core);
240 
241         Ok(())
242     }
243 
244     fn driver_install_tty(driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
245         let res = tty.install(driver.clone(), tty.clone());
246 
247         if let Err(err) = res {
248             if err == SystemError::ENOSYS {
249                 return driver.standard_install(tty);
250             } else {
251                 return Err(err);
252             }
253         }
254 
255         driver.add_tty(tty);
256 
257         Ok(())
258     }
259 
260     pub fn init_tty_device(
261         driver: Arc<TtyDriver>,
262         index: usize,
263     ) -> Result<Arc<TtyCore>, SystemError> {
264         let tty = TtyCore::new(driver.clone(), index);
265 
266         Self::driver_install_tty(driver.clone(), tty.clone())?;
267 
268         let core = tty.core();
269 
270         if core.port().is_none() {
271             let ports = driver.ports.read();
272             ports[core.index()].setup_internal_tty(Arc::downgrade(&tty));
273             tty.set_port(ports[core.index()].clone());
274         }
275 
276         TtyLdiscManager::ldisc_setup(tty.clone(), tty.core().link())?;
277 
278         Ok(tty)
279     }
280 
281     /// ## 通过设备号找到对应驱动并且初始化Tty
282     pub fn open_tty(index: usize, driver: Arc<TtyDriver>) -> Result<Arc<TtyCore>, SystemError> {
283         let tty = match driver.lookup_tty(index) {
284             Some(tty) => {
285                 // TODO: 暂时这么写,因为还没写TtyPort
286                 if tty.core().port().is_none() {
287                     kwarn!("{} port is None", tty.core().name());
288                 } else if tty.core().port().unwrap().state() == TtyPortState::KOPENED {
289                     return Err(SystemError::EBUSY);
290                 }
291 
292                 tty.reopen()?;
293                 tty
294             }
295             None => Self::init_tty_device(driver, index)?,
296         };
297 
298         return Ok(tty);
299     }
300 
301     pub fn tty_driver_type(&self) -> TtyDriverType {
302         self.tty_driver_type
303     }
304 
305     pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
306         self.tty_driver_sub_type
307     }
308 }
309 
310 impl KObject for TtyDriver {
311     fn as_any_ref(&self) -> &dyn core::any::Any {
312         todo!()
313     }
314 
315     fn set_inode(&self, _inode: Option<alloc::sync::Arc<crate::filesystem::kernfs::KernFSInode>>) {
316         todo!()
317     }
318 
319     fn inode(&self) -> Option<alloc::sync::Arc<crate::filesystem::kernfs::KernFSInode>> {
320         todo!()
321     }
322 
323     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
324         todo!()
325     }
326 
327     fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
328         todo!()
329     }
330 
331     fn kset(&self) -> Option<alloc::sync::Arc<crate::driver::base::kset::KSet>> {
332         todo!()
333     }
334 
335     fn set_kset(&self, _kset: Option<alloc::sync::Arc<crate::driver::base::kset::KSet>>) {
336         todo!()
337     }
338 
339     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
340         todo!()
341     }
342 
343     fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {
344         todo!()
345     }
346 
347     fn name(&self) -> alloc::string::String {
348         todo!()
349     }
350 
351     fn set_name(&self, _name: alloc::string::String) {
352         todo!()
353     }
354 
355     fn kobj_state(
356         &self,
357     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
358         todo!()
359     }
360 
361     fn kobj_state_mut(
362         &self,
363     ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
364         todo!()
365     }
366 
367     fn set_kobj_state(&self, _state: crate::driver::base::kobject::KObjectState) {
368         todo!()
369     }
370 }
371 
372 impl Driver for TtyDriver {
373     fn id_table(&self) -> Option<crate::driver::base::device::IdTable> {
374         todo!()
375     }
376 
377     fn devices(
378         &self,
379     ) -> alloc::vec::Vec<alloc::sync::Arc<dyn crate::driver::base::device::Device>> {
380         todo!()
381     }
382 
383     fn add_device(&self, _device: alloc::sync::Arc<dyn crate::driver::base::device::Device>) {
384         todo!()
385     }
386 
387     fn delete_device(&self, _device: &alloc::sync::Arc<dyn crate::driver::base::device::Device>) {
388         todo!()
389     }
390 
391     fn set_bus(&self, _bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
392         todo!()
393     }
394 }
395 
396 pub trait TtyOperation: Sync + Send + Debug {
397     fn install(&self, _driver: Arc<TtyDriver>, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
398         return Err(SystemError::ENOSYS);
399     }
400 
401     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError>;
402 
403     /// ## 获取可写字符数
404     fn write_room(&self, _tty: &TtyCoreData) -> usize {
405         // 默认
406         2048
407     }
408 
409     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError>;
410 
411     fn flush_chars(&self, tty: &TtyCoreData);
412 
413     fn put_char(&self, _tty: &TtyCoreData, _ch: u8) -> Result<(), SystemError> {
414         Err(SystemError::ENOSYS)
415     }
416 
417     fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
418         Err(SystemError::ENOSYS)
419     }
420 
421     fn stop(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
422         Err(SystemError::ENOSYS)
423     }
424 
425     fn flush_buffer(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
426         Err(SystemError::ENOSYS)
427     }
428 
429     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError>;
430 
431     fn chars_in_buffer(&self) -> usize {
432         0
433     }
434 
435     fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
436         Err(SystemError::ENOSYS)
437     }
438 
439     fn lookup(
440         &self,
441         _index: usize,
442         _priv_data: TtyDriverPrivateData,
443     ) -> Result<Arc<TtyCore>, SystemError> {
444         Err(SystemError::ENOSYS)
445     }
446 
447     fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
448 
449     fn resize(&self, _tty: Arc<TtyCore>, _winsize: WindowSize) -> Result<(), SystemError>;
450 }
451 
452 #[allow(dead_code)]
453 #[derive(Debug, PartialEq, Copy, Clone)]
454 pub enum TtyDriverType {
455     System,
456     Console,
457     Serial,
458     Pty,
459     Scc,
460     Syscons,
461 }
462 
463 #[allow(dead_code)]
464 #[derive(Debug, PartialEq, Copy, Clone)]
465 pub enum TtyDriverSubType {
466     Undefined,
467     Tty,
468     Console,
469     Syscons,
470     Sysptmx,
471     PtyMaster,
472     PtySlave,
473     SerialNormal,
474 }
475 
476 impl Default for TtyDriverSubType {
477     fn default() -> Self {
478         Self::Undefined
479     }
480 }
481 
482 bitflags! {
483     pub struct TtyDriverFlag: u32 {
484         /// 表示 tty 驱动程序已安装
485         const TTY_DRIVER_INSTALLED		= 0x0001;
486         /// 请求 tty 层在最后一个进程关闭设备时重置 termios 设置
487         const TTY_DRIVER_RESET_TERMIOS	= 0x0002;
488         /// 表示驱动程序将保证在设置了该标志的 tty 上不设置任何特殊字符处理标志(原模式)
489         const TTY_DRIVER_REAL_RAW		    = 0x0004;
490 
491         /// 以下四个标志位为内存分配相关,目前设计无需使用
492         const TTY_DRIVER_DYNAMIC_DEV		= 0x0008;
493         const TTY_DRIVER_DEVPTS_MEM		= 0x0010;
494         const TTY_DRIVER_HARDWARE_BREAK	= 0x0020;
495         const TTY_DRIVER_DYNAMIC_ALLOC	= 0x0040;
496 
497         /// 表示不创建带有编号的 /dev 节点。
498         /// 例如,创建 /dev/ttyprintk 而不是 /dev/ttyprintk0。仅在为单个 tty 设备分配驱动程序时适用。
499         const TTY_DRIVER_UNNUMBERED_NODE	= 0x0080;
500     }
501 }
502