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