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