xref: /DragonOS/kernel/src/driver/tty/tty_port.rs (revision a8753f8fffb992e4d3bbd21eda431081b395af6b)
1 use core::fmt::Debug;
2 
3 use alloc::sync::{Arc, Weak};
4 use kdepends::thingbuf::mpsc;
5 use system_error::SystemError;
6 
7 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
8 
9 use super::tty_core::TtyCore;
10 
11 const TTY_PORT_BUFSIZE: usize = 4096;
12 
13 #[allow(dead_code)]
14 #[derive(Debug)]
15 pub struct TtyPortData {
16     flags: i32,
17     iflags: TtyPortState,
18     sender: mpsc::Sender<u8>,
19     receiver: mpsc::Receiver<u8>,
20     tty: Weak<TtyCore>,
21     /// 内部tty,即与port直接相连的
22     internal_tty: Weak<TtyCore>,
23 }
24 
25 impl Default for TtyPortData {
26     fn default() -> Self {
27         Self::new()
28     }
29 }
30 
31 impl TtyPortData {
32     pub fn new() -> Self {
33         let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE);
34         Self {
35             flags: 0,
36             iflags: TtyPortState::Initialized,
37             sender,
38             receiver,
39             tty: Weak::new(),
40             internal_tty: Weak::new(),
41         }
42     }
43 
44     pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
45         self.internal_tty.upgrade()
46     }
47 
48     pub fn tty(&self) -> Option<Arc<TtyCore>> {
49         self.tty.upgrade()
50     }
51 }
52 
53 #[allow(dead_code)]
54 #[derive(Debug, PartialEq, Clone, Copy)]
55 pub enum TtyPortState {
56     Initialized,
57     Suspended,
58     Active,
59     CtsFlow,
60     CheckCD,
61     KOPENED,
62 }
63 
64 pub trait TtyPort: Sync + Send + Debug {
65     fn port_data(&self) -> SpinLockGuard<TtyPortData>;
66 
67     /// 获取Port的状态
68     fn state(&self) -> TtyPortState {
69         self.port_data().iflags
70     }
71 
72     /// 为port设置tty
73     fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
74         self.port_data().internal_tty = tty;
75     }
76 
77     /// 作为客户端的tty ports接收数据
78     fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
79         let tty = self.port_data().internal_tty().unwrap();
80 
81         let ld = tty.ldisc();
82 
83         let ret = ld.receive_buf2(tty.clone(), buf, None, count);
84         if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
85             return ld.receive_buf(tty, buf, None, count);
86         }
87 
88         ret
89     }
90 }
91 
92 #[derive(Debug)]
93 pub struct DefaultTtyPort {
94     port_data: SpinLock<TtyPortData>,
95 }
96 
97 impl DefaultTtyPort {
98     pub fn new() -> Self {
99         Self {
100             port_data: SpinLock::new(TtyPortData::new()),
101         }
102     }
103 }
104 
105 impl TtyPort for DefaultTtyPort {
106     fn port_data(&self) -> SpinLockGuard<TtyPortData> {
107         self.port_data.lock_irqsave()
108     }
109 }
110