xref: /DragonOS/kernel/src/driver/tty/tty_ldisc/mod.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use core::fmt::Debug;
2 
3 use alloc::sync::Arc;
4 use system_error::SystemError;
5 
6 use crate::filesystem::vfs::file::FileMode;
7 
8 use super::{
9     termios::Termios,
10     tty_core::{TtyCore, TtyCoreData, TtyFlag},
11 };
12 
13 pub mod ntty;
14 
15 pub trait TtyLineDiscipline: Sync + Send + Debug {
16     fn open(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
17     fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
18     fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
19 
20     /// ## tty行规程循环读取函数
21     ///
22     /// ### 参数
23     /// - tty: 操作的tty
24     /// - buf: 数据将被读取到buf
25     /// - len: 读取的字节长度
26     /// - cookie: 表示是否是继续上次的读,第一次读取应该传入false
27     /// - offset: 读取的偏移量
28     fn read(
29         &self,
30         tty: Arc<TtyCore>,
31         buf: &mut [u8],
32         len: usize,
33         cookie: &mut bool,
34         offset: usize,
35         mode: FileMode,
36     ) -> Result<usize, SystemError>;
37     fn write(
38         &self,
39         tty: Arc<TtyCore>,
40         buf: &[u8],
41         len: usize,
42         mode: FileMode,
43     ) -> Result<usize, SystemError>;
44     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError>;
45 
46     /// ### 设置termios后更新行规程状态
47     ///
48     /// - old: 之前的termios,如果为None则表示第一次设置
49     fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>;
50 
51     fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, SystemError>;
52     fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
53 
54     /// ## 接收数据
55     fn receive_buf(
56         &self,
57         tty: Arc<TtyCore>,
58         buf: &[u8],
59         flags: Option<&[u8]>,
60         count: usize,
61     ) -> Result<usize, SystemError>;
62 
63     /// ## 接收数据
64     fn receive_buf2(
65         &self,
66         tty: Arc<TtyCore>,
67         buf: &[u8],
68         flags: Option<&[u8]>,
69         count: usize,
70     ) -> Result<usize, SystemError>;
71 
72     /// ## 唤醒线路写者
73     fn write_wakeup(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
74         Err(SystemError::ENOSYS)
75     }
76 }
77 
78 #[derive(Debug, Clone, Copy)]
79 pub enum LineDisciplineType {
80     NTty = 0,
81 }
82 
83 impl LineDisciplineType {
84     pub fn from_line(line: u8) -> Self {
85         match line {
86             0 => Self::NTty,
87             _ => {
88                 todo!()
89             }
90         }
91     }
92 }
93 
94 pub struct TtyLdiscManager;
95 
96 impl TtyLdiscManager {
97     /// ## 为tty初始化ldisc
98     ///
99     /// ### 参数
100     /// - tty:需要设置的tty
101     /// - o_tty: other tty 用于pty pair
102     pub fn ldisc_setup(tty: Arc<TtyCore>, o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
103         let ld = tty.ldisc();
104 
105         let ret = ld.open(tty);
106         if let Err(err) = ret {
107             if err == SystemError::ENOSYS {
108                 return Err(err);
109             }
110         }
111 
112         // 处理PTY
113         if let Some(o_tty) = o_tty {
114             let ld = o_tty.ldisc();
115 
116             let ret: Result<(), SystemError> = ld.open(o_tty.clone());
117             if ret.is_err() {
118                 o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN);
119                 let _ = ld.close(o_tty.clone());
120             }
121         }
122 
123         Ok(())
124     }
125 }
126