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