1 use core::fmt::Debug; 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; 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 #[allow(dead_code)] 31 #[derive(Debug)] 32 pub struct TtyPortData { 33 flags: i32, 34 iflags: TtyPortState, 35 sender: mpsc::Sender<u8>, 36 receiver: mpsc::Receiver<u8>, 37 tty: Weak<TtyCore>, 38 } 39 40 impl TtyPortData { 41 pub fn new() -> Self { 42 let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE); 43 Self { 44 flags: 0, 45 iflags: TtyPortState::Initialized, 46 sender, 47 receiver, 48 tty: Weak::new(), 49 } 50 } 51 52 pub fn tty(&self) -> Option<Arc<TtyCore>> { 53 self.tty.upgrade() 54 } 55 } 56 57 #[allow(dead_code)] 58 #[derive(Debug, PartialEq, Clone, Copy)] 59 pub enum TtyPortState { 60 Initialized, 61 Suspended, 62 Active, 63 CtsFlow, 64 CheckCD, 65 KOPENED, 66 } 67 68 pub trait TtyPort: Sync + Send + Debug { 69 fn port_data(&self) -> SpinLockGuard<TtyPortData>; 70 71 /// 获取Port的状态 72 fn state(&self) -> TtyPortState { 73 self.port_data().iflags 74 } 75 76 /// 为port设置tty 77 fn setup_tty(&self, tty: Weak<TtyCore>) { 78 self.port_data().tty = tty; 79 } 80 81 /// 作为客户端的tty ports接收数据 82 fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> { 83 let tty = self.port_data().tty.upgrade().unwrap(); 84 85 let ld = tty.ldisc(); 86 87 let ret = ld.receive_buf2(tty.clone(), buf, None, count); 88 if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS { 89 return ld.receive_buf(tty, buf, None, count); 90 } 91 92 ret 93 } 94 } 95 96 #[derive(Debug)] 97 pub struct DefaultTtyPort { 98 port_data: SpinLock<TtyPortData>, 99 } 100 101 impl DefaultTtyPort { 102 pub fn new() -> Self { 103 Self { 104 port_data: SpinLock::new(TtyPortData::new()), 105 } 106 } 107 } 108 109 impl TtyPort for DefaultTtyPort { 110 fn port_data(&self) -> SpinLockGuard<TtyPortData> { 111 self.port_data.lock_irqsave() 112 } 113 } 114