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