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