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