xref: /DragonOS/kernel/src/driver/tty/tty_port.rs (revision 59fdb447ee4f7b53b1d9c56ec1442aa8c597ac2b)
1*59fdb447SLoGin use core::{fmt::Debug, sync::atomic::Ordering};
252da9a59SGnoCiYeH 
352da9a59SGnoCiYeH use alloc::{
452da9a59SGnoCiYeH     sync::{Arc, Weak},
552da9a59SGnoCiYeH     vec::Vec,
652da9a59SGnoCiYeH };
752da9a59SGnoCiYeH use kdepends::thingbuf::mpsc;
852da9a59SGnoCiYeH use system_error::SystemError;
952da9a59SGnoCiYeH 
1052da9a59SGnoCiYeH use crate::{
1152da9a59SGnoCiYeH     driver::tty::virtual_terminal::MAX_NR_CONSOLES,
1252da9a59SGnoCiYeH     libs::spinlock::{SpinLock, SpinLockGuard},
1352da9a59SGnoCiYeH };
1452da9a59SGnoCiYeH 
15*59fdb447SLoGin use super::{tty_core::TtyCore, virtual_terminal::virtual_console::CURRENT_VCNUM};
1652da9a59SGnoCiYeH 
1752da9a59SGnoCiYeH const TTY_PORT_BUFSIZE: usize = 4096;
1852da9a59SGnoCiYeH 
1952da9a59SGnoCiYeH lazy_static! {
2052da9a59SGnoCiYeH     pub static ref TTY_PORTS: Vec<Arc<dyn TtyPort>> = {
2152da9a59SGnoCiYeH         let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
2252da9a59SGnoCiYeH         for _ in 0..MAX_NR_CONSOLES as usize {
2352da9a59SGnoCiYeH             v.push(Arc::new(DefaultTtyPort::new()))
2452da9a59SGnoCiYeH         }
2552da9a59SGnoCiYeH 
2652da9a59SGnoCiYeH         v
2752da9a59SGnoCiYeH     };
2852da9a59SGnoCiYeH }
2952da9a59SGnoCiYeH 
30*59fdb447SLoGin /// 获取当前tty port
31*59fdb447SLoGin #[inline]
32*59fdb447SLoGin pub fn current_tty_port() -> Arc<dyn TtyPort> {
33*59fdb447SLoGin     TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
34*59fdb447SLoGin }
35*59fdb447SLoGin 
3652da9a59SGnoCiYeH #[allow(dead_code)]
3752da9a59SGnoCiYeH #[derive(Debug)]
3852da9a59SGnoCiYeH pub struct TtyPortData {
3952da9a59SGnoCiYeH     flags: i32,
4052da9a59SGnoCiYeH     iflags: TtyPortState,
4152da9a59SGnoCiYeH     sender: mpsc::Sender<u8>,
4252da9a59SGnoCiYeH     receiver: mpsc::Receiver<u8>,
4352da9a59SGnoCiYeH     tty: Weak<TtyCore>,
4452da9a59SGnoCiYeH }
4552da9a59SGnoCiYeH 
4652da9a59SGnoCiYeH impl TtyPortData {
4752da9a59SGnoCiYeH     pub fn new() -> Self {
4852da9a59SGnoCiYeH         let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE);
4952da9a59SGnoCiYeH         Self {
5052da9a59SGnoCiYeH             flags: 0,
5152da9a59SGnoCiYeH             iflags: TtyPortState::Initialized,
5252da9a59SGnoCiYeH             sender,
5352da9a59SGnoCiYeH             receiver,
5452da9a59SGnoCiYeH             tty: Weak::new(),
5552da9a59SGnoCiYeH         }
5652da9a59SGnoCiYeH     }
5752da9a59SGnoCiYeH 
5852da9a59SGnoCiYeH     pub fn tty(&self) -> Option<Arc<TtyCore>> {
5952da9a59SGnoCiYeH         self.tty.upgrade()
6052da9a59SGnoCiYeH     }
6152da9a59SGnoCiYeH }
6252da9a59SGnoCiYeH 
6352da9a59SGnoCiYeH #[allow(dead_code)]
6452da9a59SGnoCiYeH #[derive(Debug, PartialEq, Clone, Copy)]
6552da9a59SGnoCiYeH pub enum TtyPortState {
6652da9a59SGnoCiYeH     Initialized,
6752da9a59SGnoCiYeH     Suspended,
6852da9a59SGnoCiYeH     Active,
6952da9a59SGnoCiYeH     CtsFlow,
7052da9a59SGnoCiYeH     CheckCD,
7152da9a59SGnoCiYeH     KOPENED,
7252da9a59SGnoCiYeH }
7352da9a59SGnoCiYeH 
7452da9a59SGnoCiYeH pub trait TtyPort: Sync + Send + Debug {
7552da9a59SGnoCiYeH     fn port_data(&self) -> SpinLockGuard<TtyPortData>;
7652da9a59SGnoCiYeH 
7752da9a59SGnoCiYeH     /// 获取Port的状态
7852da9a59SGnoCiYeH     fn state(&self) -> TtyPortState {
7952da9a59SGnoCiYeH         self.port_data().iflags
8052da9a59SGnoCiYeH     }
8152da9a59SGnoCiYeH 
8252da9a59SGnoCiYeH     /// 为port设置tty
8352da9a59SGnoCiYeH     fn setup_tty(&self, tty: Weak<TtyCore>) {
8452da9a59SGnoCiYeH         self.port_data().tty = tty;
8552da9a59SGnoCiYeH     }
8652da9a59SGnoCiYeH 
8752da9a59SGnoCiYeH     /// 作为客户端的tty ports接收数据
8852da9a59SGnoCiYeH     fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
8952da9a59SGnoCiYeH         let tty = self.port_data().tty.upgrade().unwrap();
9052da9a59SGnoCiYeH 
9152da9a59SGnoCiYeH         let ld = tty.ldisc();
9252da9a59SGnoCiYeH 
9352da9a59SGnoCiYeH         let ret = ld.receive_buf2(tty.clone(), buf, None, count);
9452da9a59SGnoCiYeH         if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
9552da9a59SGnoCiYeH             return ld.receive_buf(tty, buf, None, count);
9652da9a59SGnoCiYeH         }
9752da9a59SGnoCiYeH 
9852da9a59SGnoCiYeH         ret
9952da9a59SGnoCiYeH     }
10052da9a59SGnoCiYeH }
10152da9a59SGnoCiYeH 
10252da9a59SGnoCiYeH #[derive(Debug)]
10352da9a59SGnoCiYeH pub struct DefaultTtyPort {
10452da9a59SGnoCiYeH     port_data: SpinLock<TtyPortData>,
10552da9a59SGnoCiYeH }
10652da9a59SGnoCiYeH 
10752da9a59SGnoCiYeH impl DefaultTtyPort {
10852da9a59SGnoCiYeH     pub fn new() -> Self {
10952da9a59SGnoCiYeH         Self {
11052da9a59SGnoCiYeH             port_data: SpinLock::new(TtyPortData::new()),
11152da9a59SGnoCiYeH         }
11252da9a59SGnoCiYeH     }
11352da9a59SGnoCiYeH }
11452da9a59SGnoCiYeH 
11552da9a59SGnoCiYeH impl TtyPort for DefaultTtyPort {
11652da9a59SGnoCiYeH     fn port_data(&self) -> SpinLockGuard<TtyPortData> {
11752da9a59SGnoCiYeH         self.port_data.lock_irqsave()
11852da9a59SGnoCiYeH     }
11952da9a59SGnoCiYeH }
120