xref: /DragonOS/kernel/src/driver/tty/tty_port.rs (revision 418ad41fd84c15ed7e132e56970150ac38fc24a9)
159fdb447SLoGin use core::{fmt::Debug, sync::atomic::Ordering};
252da9a59SGnoCiYeH 
3dfe53cf0SGnoCiYeH use alloc::sync::{Arc, Weak};
452da9a59SGnoCiYeH use kdepends::thingbuf::mpsc;
552da9a59SGnoCiYeH use system_error::SystemError;
652da9a59SGnoCiYeH 
7dfe53cf0SGnoCiYeH use crate::libs::spinlock::{SpinLock, SpinLockGuard};
852da9a59SGnoCiYeH 
9dfe53cf0SGnoCiYeH use super::{
10dfe53cf0SGnoCiYeH     tty_core::TtyCore,
11dfe53cf0SGnoCiYeH     virtual_terminal::{virtual_console::CURRENT_VCNUM, VIRT_CONSOLES},
12dfe53cf0SGnoCiYeH };
1352da9a59SGnoCiYeH 
1452da9a59SGnoCiYeH const TTY_PORT_BUFSIZE: usize = 4096;
1552da9a59SGnoCiYeH 
1659fdb447SLoGin /// 获取当前tty port
1759fdb447SLoGin #[inline]
current_tty_port() -> Arc<dyn TtyPort>1859fdb447SLoGin pub fn current_tty_port() -> Arc<dyn TtyPort> {
19dfe53cf0SGnoCiYeH     VIRT_CONSOLES[CURRENT_VCNUM.load(Ordering::SeqCst) as usize]
20dfe53cf0SGnoCiYeH         .lock_irqsave()
21dfe53cf0SGnoCiYeH         .port()
22dfe53cf0SGnoCiYeH }
23dfe53cf0SGnoCiYeH 
24dfe53cf0SGnoCiYeH #[inline]
tty_port(index: usize) -> Arc<dyn TtyPort>25dfe53cf0SGnoCiYeH pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
26dfe53cf0SGnoCiYeH     VIRT_CONSOLES[index].lock_irqsave().port()
2759fdb447SLoGin }
2859fdb447SLoGin 
2952da9a59SGnoCiYeH #[allow(dead_code)]
3052da9a59SGnoCiYeH #[derive(Debug)]
3152da9a59SGnoCiYeH pub struct TtyPortData {
3252da9a59SGnoCiYeH     flags: i32,
3352da9a59SGnoCiYeH     iflags: TtyPortState,
3452da9a59SGnoCiYeH     sender: mpsc::Sender<u8>,
3552da9a59SGnoCiYeH     receiver: mpsc::Receiver<u8>,
3652da9a59SGnoCiYeH     tty: Weak<TtyCore>,
37dfe53cf0SGnoCiYeH     /// 内部tty,即与port直接相连的
38dfe53cf0SGnoCiYeH     internal_tty: Weak<TtyCore>,
39dfe53cf0SGnoCiYeH }
40dfe53cf0SGnoCiYeH 
41dfe53cf0SGnoCiYeH impl Default for TtyPortData {
default() -> Self42dfe53cf0SGnoCiYeH     fn default() -> Self {
43dfe53cf0SGnoCiYeH         Self::new()
44dfe53cf0SGnoCiYeH     }
4552da9a59SGnoCiYeH }
4652da9a59SGnoCiYeH 
4752da9a59SGnoCiYeH impl TtyPortData {
new() -> Self4852da9a59SGnoCiYeH     pub fn new() -> Self {
4952da9a59SGnoCiYeH         let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE);
5052da9a59SGnoCiYeH         Self {
5152da9a59SGnoCiYeH             flags: 0,
5252da9a59SGnoCiYeH             iflags: TtyPortState::Initialized,
5352da9a59SGnoCiYeH             sender,
5452da9a59SGnoCiYeH             receiver,
5552da9a59SGnoCiYeH             tty: Weak::new(),
56dfe53cf0SGnoCiYeH             internal_tty: Weak::new(),
5752da9a59SGnoCiYeH         }
5852da9a59SGnoCiYeH     }
5952da9a59SGnoCiYeH 
internal_tty(&self) -> Option<Arc<TtyCore>>60dfe53cf0SGnoCiYeH     pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
61dfe53cf0SGnoCiYeH         self.internal_tty.upgrade()
6252da9a59SGnoCiYeH     }
63*418ad41fSLoGin 
tty(&self) -> Option<Arc<TtyCore>>64*418ad41fSLoGin     pub fn tty(&self) -> Option<Arc<TtyCore>> {
65*418ad41fSLoGin         self.tty.upgrade()
66*418ad41fSLoGin     }
6752da9a59SGnoCiYeH }
6852da9a59SGnoCiYeH 
6952da9a59SGnoCiYeH #[allow(dead_code)]
7052da9a59SGnoCiYeH #[derive(Debug, PartialEq, Clone, Copy)]
7152da9a59SGnoCiYeH pub enum TtyPortState {
7252da9a59SGnoCiYeH     Initialized,
7352da9a59SGnoCiYeH     Suspended,
7452da9a59SGnoCiYeH     Active,
7552da9a59SGnoCiYeH     CtsFlow,
7652da9a59SGnoCiYeH     CheckCD,
7752da9a59SGnoCiYeH     KOPENED,
7852da9a59SGnoCiYeH }
7952da9a59SGnoCiYeH 
8052da9a59SGnoCiYeH pub trait TtyPort: Sync + Send + Debug {
port_data(&self) -> SpinLockGuard<TtyPortData>8152da9a59SGnoCiYeH     fn port_data(&self) -> SpinLockGuard<TtyPortData>;
8252da9a59SGnoCiYeH 
8352da9a59SGnoCiYeH     /// 获取Port的状态
state(&self) -> TtyPortState8452da9a59SGnoCiYeH     fn state(&self) -> TtyPortState {
8552da9a59SGnoCiYeH         self.port_data().iflags
8652da9a59SGnoCiYeH     }
8752da9a59SGnoCiYeH 
8852da9a59SGnoCiYeH     /// 为port设置tty
setup_internal_tty(&self, tty: Weak<TtyCore>)89dfe53cf0SGnoCiYeH     fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
90dfe53cf0SGnoCiYeH         self.port_data().internal_tty = tty;
9152da9a59SGnoCiYeH     }
9252da9a59SGnoCiYeH 
9352da9a59SGnoCiYeH     /// 作为客户端的tty ports接收数据
receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError>9452da9a59SGnoCiYeH     fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
95dfe53cf0SGnoCiYeH         let tty = self.port_data().internal_tty().unwrap();
9652da9a59SGnoCiYeH 
9752da9a59SGnoCiYeH         let ld = tty.ldisc();
9852da9a59SGnoCiYeH 
9952da9a59SGnoCiYeH         let ret = ld.receive_buf2(tty.clone(), buf, None, count);
10052da9a59SGnoCiYeH         if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
10152da9a59SGnoCiYeH             return ld.receive_buf(tty, buf, None, count);
10252da9a59SGnoCiYeH         }
10352da9a59SGnoCiYeH 
10452da9a59SGnoCiYeH         ret
10552da9a59SGnoCiYeH     }
10652da9a59SGnoCiYeH }
10752da9a59SGnoCiYeH 
10852da9a59SGnoCiYeH #[derive(Debug)]
10952da9a59SGnoCiYeH pub struct DefaultTtyPort {
11052da9a59SGnoCiYeH     port_data: SpinLock<TtyPortData>,
11152da9a59SGnoCiYeH }
11252da9a59SGnoCiYeH 
11352da9a59SGnoCiYeH impl DefaultTtyPort {
new() -> Self11452da9a59SGnoCiYeH     pub fn new() -> Self {
11552da9a59SGnoCiYeH         Self {
11652da9a59SGnoCiYeH             port_data: SpinLock::new(TtyPortData::new()),
11752da9a59SGnoCiYeH         }
11852da9a59SGnoCiYeH     }
11952da9a59SGnoCiYeH }
12052da9a59SGnoCiYeH 
12152da9a59SGnoCiYeH impl TtyPort for DefaultTtyPort {
port_data(&self) -> SpinLockGuard<TtyPortData>12252da9a59SGnoCiYeH     fn port_data(&self) -> SpinLockGuard<TtyPortData> {
12352da9a59SGnoCiYeH         self.port_data.lock_irqsave()
12452da9a59SGnoCiYeH     }
12552da9a59SGnoCiYeH }
126