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]
current_tty_port() -> Arc<dyn TtyPort>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 {
new() -> Self47 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
tty(&self) -> Option<Arc<TtyCore>>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 {
port_data(&self) -> SpinLockGuard<TtyPortData>75 fn port_data(&self) -> SpinLockGuard<TtyPortData>;
76
77 /// 获取Port的状态
state(&self) -> TtyPortState78 fn state(&self) -> TtyPortState {
79 self.port_data().iflags
80 }
81
82 /// 为port设置tty
setup_tty(&self, tty: Weak<TtyCore>)83 fn setup_tty(&self, tty: Weak<TtyCore>) {
84 self.port_data().tty = tty;
85 }
86
87 /// 作为客户端的tty ports接收数据
receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError>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 {
new() -> Self108 pub fn new() -> Self {
109 Self {
110 port_data: SpinLock::new(TtyPortData::new()),
111 }
112 }
113 }
114
115 impl TtyPort for DefaultTtyPort {
port_data(&self) -> SpinLockGuard<TtyPortData>116 fn port_data(&self) -> SpinLockGuard<TtyPortData> {
117 self.port_data.lock_irqsave()
118 }
119 }
120