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