1 use core::{fmt::Debug, sync::atomic::Ordering};
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, virtual_terminal::virtual_console::CURRENT_VCNUM};
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 /// 获取当前tty port
31 #[inline]
current_tty_port() -> Arc<dyn TtyPort>32 pub fn current_tty_port() -> Arc<dyn TtyPort> {
33     TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
34 }
35 
36 #[allow(dead_code)]
37 #[derive(Debug)]
38 pub struct TtyPortData {
39     flags: i32,
40     iflags: TtyPortState,
41     sender: mpsc::Sender<u8>,
42     receiver: mpsc::Receiver<u8>,
43     tty: Weak<TtyCore>,
44 }
45 
46 impl TtyPortData {
new() -> Self47     pub fn new() -> Self {
48         let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE);
49         Self {
50             flags: 0,
51             iflags: TtyPortState::Initialized,
52             sender,
53             receiver,
54             tty: Weak::new(),
55         }
56     }
57 
tty(&self) -> Option<Arc<TtyCore>>58     pub fn tty(&self) -> Option<Arc<TtyCore>> {
59         self.tty.upgrade()
60     }
61 }
62 
63 #[allow(dead_code)]
64 #[derive(Debug, PartialEq, Clone, Copy)]
65 pub enum TtyPortState {
66     Initialized,
67     Suspended,
68     Active,
69     CtsFlow,
70     CheckCD,
71     KOPENED,
72 }
73 
74 pub trait TtyPort: Sync + Send + Debug {
port_data(&self) -> SpinLockGuard<TtyPortData>75     fn port_data(&self) -> SpinLockGuard<TtyPortData>;
76 
77     /// 获取Port的状态
state(&self) -> TtyPortState78     fn state(&self) -> TtyPortState {
79         self.port_data().iflags
80     }
81 
82     /// 为port设置tty
setup_tty(&self, tty: Weak<TtyCore>)83     fn setup_tty(&self, tty: Weak<TtyCore>) {
84         self.port_data().tty = tty;
85     }
86 
87     /// 作为客户端的tty ports接收数据
receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError>88     fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
89         let tty = self.port_data().tty.upgrade().unwrap();
90 
91         let ld = tty.ldisc();
92 
93         let ret = ld.receive_buf2(tty.clone(), buf, None, count);
94         if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
95             return ld.receive_buf(tty, buf, None, count);
96         }
97 
98         ret
99     }
100 }
101 
102 #[derive(Debug)]
103 pub struct DefaultTtyPort {
104     port_data: SpinLock<TtyPortData>,
105 }
106 
107 impl DefaultTtyPort {
new() -> Self108     pub fn new() -> Self {
109         Self {
110             port_data: SpinLock::new(TtyPortData::new()),
111         }
112     }
113 }
114 
115 impl TtyPort for DefaultTtyPort {
port_data(&self) -> SpinLockGuard<TtyPortData>116     fn port_data(&self) -> SpinLockGuard<TtyPortData> {
117         self.port_data.lock_irqsave()
118     }
119 }
120