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