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