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