xref: /DragonOS/kernel/src/driver/tty/tty_core.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
159fdb447SLoGin use core::{
259fdb447SLoGin     fmt::Debug,
3*dfe53cf0SGnoCiYeH     sync::atomic::{AtomicBool, AtomicUsize, Ordering},
459fdb447SLoGin };
552da9a59SGnoCiYeH 
6*dfe53cf0SGnoCiYeH use alloc::{
7*dfe53cf0SGnoCiYeH     collections::LinkedList,
8*dfe53cf0SGnoCiYeH     string::String,
9*dfe53cf0SGnoCiYeH     sync::{Arc, Weak},
10*dfe53cf0SGnoCiYeH     vec::Vec,
11*dfe53cf0SGnoCiYeH };
1252da9a59SGnoCiYeH use system_error::SystemError;
1352da9a59SGnoCiYeH 
1452da9a59SGnoCiYeH use crate::{
15f3b05a97SGnoCiYeH     driver::serial::serial8250::send_to_default_serial8250_port,
1652da9a59SGnoCiYeH     libs::{
1752da9a59SGnoCiYeH         rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
1852da9a59SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
1952da9a59SGnoCiYeH         wait_queue::EventWaitQueue,
2052da9a59SGnoCiYeH     },
2152da9a59SGnoCiYeH     mm::VirtAddr,
2252bcb59eSGnoCiYeH     net::event_poll::{EPollEventType, EPollItem},
2352da9a59SGnoCiYeH     process::Pid,
24be60c929SGnoCiYeH     syscall::user_access::{UserBufferReader, UserBufferWriter},
2552da9a59SGnoCiYeH };
2652da9a59SGnoCiYeH 
2752da9a59SGnoCiYeH use super::{
2852da9a59SGnoCiYeH     termios::{ControlMode, PosixTermios, Termios, TtySetTermiosOpt, WindowSize},
2952da9a59SGnoCiYeH     tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
3052da9a59SGnoCiYeH     tty_ldisc::{
3152da9a59SGnoCiYeH         ntty::{NTtyData, NTtyLinediscipline},
3252da9a59SGnoCiYeH         TtyLineDiscipline,
3352da9a59SGnoCiYeH     },
3452da9a59SGnoCiYeH     tty_port::TtyPort,
3552da9a59SGnoCiYeH     virtual_terminal::{virtual_console::VirtualConsoleData, VIRT_CONSOLES},
3652da9a59SGnoCiYeH };
3752da9a59SGnoCiYeH 
3852da9a59SGnoCiYeH #[derive(Debug)]
3952da9a59SGnoCiYeH pub struct TtyCore {
4052da9a59SGnoCiYeH     core: TtyCoreData,
4152da9a59SGnoCiYeH     /// 线路规程函数集
4252da9a59SGnoCiYeH     line_discipline: Arc<dyn TtyLineDiscipline>,
4352da9a59SGnoCiYeH }
4452da9a59SGnoCiYeH 
4552da9a59SGnoCiYeH impl TtyCore {
4652da9a59SGnoCiYeH     pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
4752da9a59SGnoCiYeH         let name = driver.tty_line_name(index);
4852da9a59SGnoCiYeH         let termios = driver.init_termios();
4952da9a59SGnoCiYeH         let core = TtyCoreData {
5052da9a59SGnoCiYeH             tty_driver: driver,
5152da9a59SGnoCiYeH             termios: RwLock::new(termios),
5252da9a59SGnoCiYeH             name,
5352da9a59SGnoCiYeH             flags: RwLock::new(TtyFlag::empty()),
5459fdb447SLoGin             count: AtomicUsize::new(0),
5552da9a59SGnoCiYeH             window_size: RwLock::new(WindowSize::default()),
5652da9a59SGnoCiYeH             read_wq: EventWaitQueue::new(),
5752da9a59SGnoCiYeH             write_wq: EventWaitQueue::new(),
5852da9a59SGnoCiYeH             port: RwLock::new(None),
5952da9a59SGnoCiYeH             index,
6052da9a59SGnoCiYeH             ctrl: SpinLock::new(TtyContorlInfo::default()),
6152da9a59SGnoCiYeH             closing: AtomicBool::new(false),
6252da9a59SGnoCiYeH             flow: SpinLock::new(TtyFlowState::default()),
63*dfe53cf0SGnoCiYeH             link: RwLock::default(),
6452bcb59eSGnoCiYeH             epitems: SpinLock::new(LinkedList::new()),
6552da9a59SGnoCiYeH         };
6652da9a59SGnoCiYeH 
6752da9a59SGnoCiYeH         return Arc::new(Self {
6852da9a59SGnoCiYeH             core,
6952da9a59SGnoCiYeH             line_discipline: Arc::new(NTtyLinediscipline {
7052da9a59SGnoCiYeH                 data: SpinLock::new(NTtyData::new()),
7152da9a59SGnoCiYeH             }),
7252da9a59SGnoCiYeH         });
7352da9a59SGnoCiYeH     }
7452da9a59SGnoCiYeH 
7552da9a59SGnoCiYeH     #[inline]
7652da9a59SGnoCiYeH     pub fn core(&self) -> &TtyCoreData {
7752da9a59SGnoCiYeH         return &self.core;
7852da9a59SGnoCiYeH     }
7952da9a59SGnoCiYeH 
8052da9a59SGnoCiYeH     #[inline]
8152da9a59SGnoCiYeH     pub fn ldisc(&self) -> Arc<dyn TtyLineDiscipline> {
8252da9a59SGnoCiYeH         self.line_discipline.clone()
8352da9a59SGnoCiYeH     }
8452da9a59SGnoCiYeH 
85f3b05a97SGnoCiYeH     pub fn write_without_serial(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
86f3b05a97SGnoCiYeH         self.core
87f3b05a97SGnoCiYeH             .driver()
88f3b05a97SGnoCiYeH             .driver_funcs()
89f3b05a97SGnoCiYeH             .write(self.core(), buf, nr)
90f3b05a97SGnoCiYeH     }
91f3b05a97SGnoCiYeH 
9252da9a59SGnoCiYeH     pub fn reopen(&self) -> Result<(), SystemError> {
9352da9a59SGnoCiYeH         let tty_core = self.core();
9452da9a59SGnoCiYeH         let driver = tty_core.driver();
9552da9a59SGnoCiYeH 
9652da9a59SGnoCiYeH         if driver.tty_driver_type() == TtyDriverType::Pty
9752da9a59SGnoCiYeH             && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster
9852da9a59SGnoCiYeH         {
9952da9a59SGnoCiYeH             return Err(SystemError::EIO);
10052da9a59SGnoCiYeH         }
10152da9a59SGnoCiYeH 
10252da9a59SGnoCiYeH         // if *tty_core.count.read() == 0 {
10352da9a59SGnoCiYeH         //     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
10452da9a59SGnoCiYeH         // }
10552da9a59SGnoCiYeH 
10652da9a59SGnoCiYeH         // TODO 判断flags
10752da9a59SGnoCiYeH 
10852da9a59SGnoCiYeH         tty_core.add_count();
10952da9a59SGnoCiYeH 
11052da9a59SGnoCiYeH         Ok(())
11152da9a59SGnoCiYeH     }
11252da9a59SGnoCiYeH 
11352da9a59SGnoCiYeH     #[inline]
11452da9a59SGnoCiYeH     pub fn set_port(&self, port: Arc<dyn TtyPort>) {
11552da9a59SGnoCiYeH         *self.core.port.write() = Some(port);
11652da9a59SGnoCiYeH     }
11752da9a59SGnoCiYeH 
11852da9a59SGnoCiYeH     pub fn tty_start(&self) {
11952da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
12052da9a59SGnoCiYeH         if !flow.stopped || flow.tco_stopped {
12152da9a59SGnoCiYeH             return;
12252da9a59SGnoCiYeH         }
12352da9a59SGnoCiYeH 
12452da9a59SGnoCiYeH         flow.stopped = false;
12552da9a59SGnoCiYeH         let _ = self.start(self.core());
12652da9a59SGnoCiYeH         self.tty_wakeup();
12752da9a59SGnoCiYeH     }
12852da9a59SGnoCiYeH 
12952da9a59SGnoCiYeH     pub fn tty_stop(&self) {
13052da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
13152da9a59SGnoCiYeH         if flow.stopped {
13252da9a59SGnoCiYeH             return;
13352da9a59SGnoCiYeH         }
13452da9a59SGnoCiYeH         flow.stopped = true;
13552da9a59SGnoCiYeH 
13652da9a59SGnoCiYeH         let _ = self.stop(self.core());
13752da9a59SGnoCiYeH     }
13852da9a59SGnoCiYeH 
13952da9a59SGnoCiYeH     pub fn tty_wakeup(&self) {
14059fdb447SLoGin         if self.core.flags().contains(TtyFlag::DO_WRITE_WAKEUP) {
14152da9a59SGnoCiYeH             let _ = self.ldisc().write_wakeup(self.core());
14252da9a59SGnoCiYeH         }
14352da9a59SGnoCiYeH 
14452da9a59SGnoCiYeH         self.core()
14552da9a59SGnoCiYeH             .write_wq
146*dfe53cf0SGnoCiYeH             .wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
14752da9a59SGnoCiYeH     }
14852da9a59SGnoCiYeH 
149be60c929SGnoCiYeH     pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
150be60c929SGnoCiYeH         let core = tty.core();
151b5b571e0SLoGin         let real_tty = if core.driver().tty_driver_type() == TtyDriverType::Pty
152be60c929SGnoCiYeH             && core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster
153be60c929SGnoCiYeH         {
154b5b571e0SLoGin             core.link().unwrap()
155be60c929SGnoCiYeH         } else {
156b5b571e0SLoGin             tty
157b5b571e0SLoGin         };
15852da9a59SGnoCiYeH         match cmd {
15952da9a59SGnoCiYeH             TtyIoctlCmd::TCGETS => {
160b5b571e0SLoGin                 let termios = PosixTermios::from_kernel_termios(*real_tty.core.termios());
16152da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
16252da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<PosixTermios>(),
16352da9a59SGnoCiYeH                     core::mem::size_of::<PosixTermios>(),
16452da9a59SGnoCiYeH                     true,
16552da9a59SGnoCiYeH                 )?;
16652da9a59SGnoCiYeH 
16752da9a59SGnoCiYeH                 user_writer.copy_one_to_user(&termios, 0)?;
16852da9a59SGnoCiYeH                 return Ok(0);
16952da9a59SGnoCiYeH             }
17052bcb59eSGnoCiYeH             TtyIoctlCmd::TCSETS => {
17152bcb59eSGnoCiYeH                 return TtyCore::core_set_termios(
17252bcb59eSGnoCiYeH                     real_tty,
17352bcb59eSGnoCiYeH                     VirtAddr::new(arg),
17452bcb59eSGnoCiYeH                     TtySetTermiosOpt::TERMIOS_OLD,
17552bcb59eSGnoCiYeH                 );
17652bcb59eSGnoCiYeH             }
17752da9a59SGnoCiYeH             TtyIoctlCmd::TCSETSW => {
178be60c929SGnoCiYeH                 return TtyCore::core_set_termios(
179be60c929SGnoCiYeH                     real_tty,
18052da9a59SGnoCiYeH                     VirtAddr::new(arg),
18152da9a59SGnoCiYeH                     TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD,
18252da9a59SGnoCiYeH                 );
18352da9a59SGnoCiYeH             }
18452da9a59SGnoCiYeH             _ => {
18552da9a59SGnoCiYeH                 return Err(SystemError::ENOIOCTLCMD);
18652da9a59SGnoCiYeH             }
18752da9a59SGnoCiYeH         }
18852da9a59SGnoCiYeH     }
18952da9a59SGnoCiYeH 
19052da9a59SGnoCiYeH     pub fn core_set_termios(
19152da9a59SGnoCiYeH         tty: Arc<TtyCore>,
19252da9a59SGnoCiYeH         arg: VirtAddr,
19352da9a59SGnoCiYeH         opt: TtySetTermiosOpt,
19452da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
195be60c929SGnoCiYeH         #[allow(unused_assignments)]
196be60c929SGnoCiYeH         // TERMIOS_TERMIO下会用到
197b5b571e0SLoGin         let mut tmp_termios = *tty.core().termios();
19852da9a59SGnoCiYeH 
19952da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
20052da9a59SGnoCiYeH             todo!()
20152da9a59SGnoCiYeH         } else {
202be60c929SGnoCiYeH             let user_reader = UserBufferReader::new(
20352da9a59SGnoCiYeH                 arg.as_ptr::<PosixTermios>(),
20452da9a59SGnoCiYeH                 core::mem::size_of::<PosixTermios>(),
20552da9a59SGnoCiYeH                 true,
20652da9a59SGnoCiYeH             )?;
20752da9a59SGnoCiYeH 
208be60c929SGnoCiYeH             let mut term = PosixTermios::default();
209be60c929SGnoCiYeH             user_reader.copy_one_from_user(&mut term, 0)?;
210be60c929SGnoCiYeH 
211be60c929SGnoCiYeH             tmp_termios = term.to_kernel_termios();
21252da9a59SGnoCiYeH         }
21352da9a59SGnoCiYeH 
21452da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) {
215be60c929SGnoCiYeH             let ld = tty.ldisc();
21652da9a59SGnoCiYeH             let _ = ld.flush_buffer(tty.clone());
21752da9a59SGnoCiYeH         }
21852da9a59SGnoCiYeH 
21952da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_WAIT) {
22052da9a59SGnoCiYeH             // TODO
22152da9a59SGnoCiYeH         }
22252da9a59SGnoCiYeH 
223be60c929SGnoCiYeH         TtyCore::set_termios_next(tty, tmp_termios)?;
22452da9a59SGnoCiYeH         Ok(0)
22552da9a59SGnoCiYeH     }
22652da9a59SGnoCiYeH 
227be60c929SGnoCiYeH     pub fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> {
228be60c929SGnoCiYeH         let mut termios = tty.core().termios_write();
22952da9a59SGnoCiYeH 
230b5b571e0SLoGin         let old_termios = *termios;
23152da9a59SGnoCiYeH         *termios = new_termios;
23252da9a59SGnoCiYeH         let tmp = termios.control_mode;
23352da9a59SGnoCiYeH         termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
23452da9a59SGnoCiYeH 
235be60c929SGnoCiYeH         let ret = tty.set_termios(tty.clone(), old_termios);
23652da9a59SGnoCiYeH         if ret.is_err() {
23752da9a59SGnoCiYeH             termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
23852da9a59SGnoCiYeH             termios.control_mode |= old_termios.control_mode
23952da9a59SGnoCiYeH                 & !(ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL);
24052da9a59SGnoCiYeH             termios.input_speed = old_termios.input_speed;
24152da9a59SGnoCiYeH             termios.output_speed = old_termios.output_speed;
24252da9a59SGnoCiYeH         }
24352da9a59SGnoCiYeH 
24452da9a59SGnoCiYeH         drop(termios);
245be60c929SGnoCiYeH         let ld = tty.ldisc();
24652da9a59SGnoCiYeH         ld.set_termios(tty, Some(old_termios))?;
24752da9a59SGnoCiYeH 
24852da9a59SGnoCiYeH         Ok(())
24952da9a59SGnoCiYeH     }
25052da9a59SGnoCiYeH }
25152da9a59SGnoCiYeH 
252b5b571e0SLoGin #[derive(Debug, Default)]
25352da9a59SGnoCiYeH pub struct TtyContorlInfo {
25452da9a59SGnoCiYeH     /// 前台进程pid
25552da9a59SGnoCiYeH     pub session: Option<Pid>,
25652da9a59SGnoCiYeH     /// 前台进程组id
25752da9a59SGnoCiYeH     pub pgid: Option<Pid>,
25852da9a59SGnoCiYeH 
25952da9a59SGnoCiYeH     /// packet模式下使用,目前未用到
260*dfe53cf0SGnoCiYeH     pub pktstatus: TtyPacketStatus,
26152da9a59SGnoCiYeH     pub packet: bool,
26252da9a59SGnoCiYeH }
26352da9a59SGnoCiYeH 
26452da9a59SGnoCiYeH #[derive(Debug, Default)]
26552da9a59SGnoCiYeH pub struct TtyCoreWriteData {
26652da9a59SGnoCiYeH     /// 写缓冲区
26752da9a59SGnoCiYeH     pub write_buf: Vec<u8>,
26852da9a59SGnoCiYeH     /// 写入数量
26952da9a59SGnoCiYeH     pub write_cnt: usize,
27052da9a59SGnoCiYeH }
27152da9a59SGnoCiYeH 
27252da9a59SGnoCiYeH #[derive(Debug, Default)]
27352da9a59SGnoCiYeH pub struct TtyFlowState {
27452da9a59SGnoCiYeH     /// 表示流控是否被停止
27552da9a59SGnoCiYeH     pub stopped: bool,
27652da9a59SGnoCiYeH     /// 表示 TCO(Transmit Continuous Operation)流控是否被停止
27752da9a59SGnoCiYeH     pub tco_stopped: bool,
27852da9a59SGnoCiYeH }
27952da9a59SGnoCiYeH 
28052da9a59SGnoCiYeH #[derive(Debug)]
28152da9a59SGnoCiYeH pub struct TtyCoreData {
28252da9a59SGnoCiYeH     tty_driver: Arc<TtyDriver>,
28352da9a59SGnoCiYeH     termios: RwLock<Termios>,
28452da9a59SGnoCiYeH     name: String,
28552da9a59SGnoCiYeH     flags: RwLock<TtyFlag>,
28652da9a59SGnoCiYeH     /// 在初始化时即确定不会更改,所以这里不用加锁
28752da9a59SGnoCiYeH     index: usize,
28859fdb447SLoGin     count: AtomicUsize,
28952da9a59SGnoCiYeH     /// 窗口大小
29052da9a59SGnoCiYeH     window_size: RwLock<WindowSize>,
29152da9a59SGnoCiYeH     /// 读等待队列
29252da9a59SGnoCiYeH     read_wq: EventWaitQueue,
29352da9a59SGnoCiYeH     /// 写等待队列
29452da9a59SGnoCiYeH     write_wq: EventWaitQueue,
29552da9a59SGnoCiYeH     /// 端口
29652da9a59SGnoCiYeH     port: RwLock<Option<Arc<dyn TtyPort>>>,
29752da9a59SGnoCiYeH     /// 前台进程
29852da9a59SGnoCiYeH     ctrl: SpinLock<TtyContorlInfo>,
29952da9a59SGnoCiYeH     /// 是否正在关闭
30052da9a59SGnoCiYeH     closing: AtomicBool,
30152da9a59SGnoCiYeH     /// 流控状态
30252da9a59SGnoCiYeH     flow: SpinLock<TtyFlowState>,
303be60c929SGnoCiYeH     /// 链接tty
304*dfe53cf0SGnoCiYeH     link: RwLock<Weak<TtyCore>>,
30552bcb59eSGnoCiYeH     /// epitems
30652bcb59eSGnoCiYeH     epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
30752da9a59SGnoCiYeH }
30852da9a59SGnoCiYeH 
30952da9a59SGnoCiYeH impl TtyCoreData {
31052da9a59SGnoCiYeH     #[inline]
31152da9a59SGnoCiYeH     pub fn driver(&self) -> Arc<TtyDriver> {
31252da9a59SGnoCiYeH         self.tty_driver.clone()
31352da9a59SGnoCiYeH     }
31452da9a59SGnoCiYeH 
31552da9a59SGnoCiYeH     #[inline]
31652da9a59SGnoCiYeH     pub fn flow_irqsave(&self) -> SpinLockGuard<TtyFlowState> {
31752da9a59SGnoCiYeH         self.flow.lock_irqsave()
31852da9a59SGnoCiYeH     }
31952da9a59SGnoCiYeH 
32052da9a59SGnoCiYeH     #[inline]
32152da9a59SGnoCiYeH     pub fn port(&self) -> Option<Arc<dyn TtyPort>> {
32252da9a59SGnoCiYeH         self.port.read().clone()
32352da9a59SGnoCiYeH     }
32452da9a59SGnoCiYeH 
32552da9a59SGnoCiYeH     #[inline]
32652da9a59SGnoCiYeH     pub fn index(&self) -> usize {
32752da9a59SGnoCiYeH         self.index
32852da9a59SGnoCiYeH     }
32952da9a59SGnoCiYeH 
33052da9a59SGnoCiYeH     #[inline]
33152da9a59SGnoCiYeH     pub fn name(&self) -> String {
33252da9a59SGnoCiYeH         self.name.clone()
33352da9a59SGnoCiYeH     }
33452da9a59SGnoCiYeH 
33552da9a59SGnoCiYeH     #[inline]
33652da9a59SGnoCiYeH     pub fn flags(&self) -> TtyFlag {
337b5b571e0SLoGin         *self.flags.read_irqsave()
33852da9a59SGnoCiYeH     }
33952da9a59SGnoCiYeH 
34052da9a59SGnoCiYeH     #[inline]
341*dfe53cf0SGnoCiYeH     pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
342*dfe53cf0SGnoCiYeH         self.flags.write_irqsave()
343*dfe53cf0SGnoCiYeH     }
344*dfe53cf0SGnoCiYeH 
345*dfe53cf0SGnoCiYeH     #[inline]
34652da9a59SGnoCiYeH     pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
34752bcb59eSGnoCiYeH         self.termios.read_irqsave()
34852da9a59SGnoCiYeH     }
34952da9a59SGnoCiYeH 
35052da9a59SGnoCiYeH     #[inline]
35152da9a59SGnoCiYeH     pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
35252bcb59eSGnoCiYeH         self.termios.write_irqsave()
35352da9a59SGnoCiYeH     }
35452da9a59SGnoCiYeH 
35552da9a59SGnoCiYeH     #[inline]
35652da9a59SGnoCiYeH     pub fn set_termios(&self, termios: Termios) {
35759fdb447SLoGin         let mut termios_guard = self.termios_write();
35852da9a59SGnoCiYeH         *termios_guard = termios;
35952da9a59SGnoCiYeH     }
36052da9a59SGnoCiYeH 
36152da9a59SGnoCiYeH     #[inline]
362*dfe53cf0SGnoCiYeH     pub fn count(&self) -> usize {
363*dfe53cf0SGnoCiYeH         self.count.load(Ordering::SeqCst)
364*dfe53cf0SGnoCiYeH     }
365*dfe53cf0SGnoCiYeH 
366*dfe53cf0SGnoCiYeH     #[inline]
36752da9a59SGnoCiYeH     pub fn add_count(&self) {
36859fdb447SLoGin         self.count
36959fdb447SLoGin             .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
37052da9a59SGnoCiYeH     }
37152da9a59SGnoCiYeH 
37252da9a59SGnoCiYeH     #[inline]
37352da9a59SGnoCiYeH     pub fn read_wq(&self) -> &EventWaitQueue {
37452da9a59SGnoCiYeH         &self.read_wq
37552da9a59SGnoCiYeH     }
37652da9a59SGnoCiYeH 
37752da9a59SGnoCiYeH     #[inline]
37852da9a59SGnoCiYeH     pub fn write_wq(&self) -> &EventWaitQueue {
37952da9a59SGnoCiYeH         &self.write_wq
38052da9a59SGnoCiYeH     }
38152da9a59SGnoCiYeH 
38252da9a59SGnoCiYeH     #[inline]
38352da9a59SGnoCiYeH     pub fn contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo> {
38452da9a59SGnoCiYeH         self.ctrl.lock_irqsave()
38552da9a59SGnoCiYeH     }
38652da9a59SGnoCiYeH 
38752da9a59SGnoCiYeH     #[inline]
38852da9a59SGnoCiYeH     pub fn window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize> {
38952da9a59SGnoCiYeH         self.window_size.upgradeable_read()
39052da9a59SGnoCiYeH     }
39152da9a59SGnoCiYeH 
39252da9a59SGnoCiYeH     #[inline]
39352da9a59SGnoCiYeH     pub fn window_size(&self) -> RwLockReadGuard<WindowSize> {
39452da9a59SGnoCiYeH         self.window_size.read()
39552da9a59SGnoCiYeH     }
39652da9a59SGnoCiYeH 
39752da9a59SGnoCiYeH     #[inline]
39852da9a59SGnoCiYeH     pub fn is_closing(&self) -> bool {
39952da9a59SGnoCiYeH         self.closing.load(core::sync::atomic::Ordering::SeqCst)
40052da9a59SGnoCiYeH     }
40152da9a59SGnoCiYeH 
40252da9a59SGnoCiYeH     #[inline]
40352da9a59SGnoCiYeH     pub fn vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData> {
40452da9a59SGnoCiYeH         VIRT_CONSOLES[self.index].lock_irqsave()
40552da9a59SGnoCiYeH     }
406be60c929SGnoCiYeH 
407be60c929SGnoCiYeH     #[inline]
408be60c929SGnoCiYeH     pub fn link(&self) -> Option<Arc<TtyCore>> {
409*dfe53cf0SGnoCiYeH         self.link.read().upgrade()
410*dfe53cf0SGnoCiYeH     }
411*dfe53cf0SGnoCiYeH 
412*dfe53cf0SGnoCiYeH     pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> {
413*dfe53cf0SGnoCiYeH         if let Some(link) = self.link() {
414*dfe53cf0SGnoCiYeH             return Ok(link);
415*dfe53cf0SGnoCiYeH         }
416*dfe53cf0SGnoCiYeH         return Err(SystemError::ENODEV);
417*dfe53cf0SGnoCiYeH     }
418*dfe53cf0SGnoCiYeH 
419*dfe53cf0SGnoCiYeH     pub fn set_link(&self, link: Weak<TtyCore>) {
420*dfe53cf0SGnoCiYeH         *self.link.write() = link;
421*dfe53cf0SGnoCiYeH     }
422*dfe53cf0SGnoCiYeH 
423*dfe53cf0SGnoCiYeH     pub fn init_termios(&self) {
424*dfe53cf0SGnoCiYeH         let tty_index = self.index();
425*dfe53cf0SGnoCiYeH         let driver = self.driver();
426*dfe53cf0SGnoCiYeH         // 初始化termios
427*dfe53cf0SGnoCiYeH         if !driver
428*dfe53cf0SGnoCiYeH             .flags()
429*dfe53cf0SGnoCiYeH             .contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS)
430*dfe53cf0SGnoCiYeH         {
431*dfe53cf0SGnoCiYeH             // 先查看是否有已经保存的termios
432*dfe53cf0SGnoCiYeH             if let Some(t) = driver.saved_termios().get(tty_index) {
433*dfe53cf0SGnoCiYeH                 let mut termios = *t;
434*dfe53cf0SGnoCiYeH                 termios.line = driver.init_termios().line;
435*dfe53cf0SGnoCiYeH                 self.set_termios(termios);
436*dfe53cf0SGnoCiYeH             }
437*dfe53cf0SGnoCiYeH         }
438*dfe53cf0SGnoCiYeH         // TODO:设置termios波特率?
439be60c929SGnoCiYeH     }
44052bcb59eSGnoCiYeH 
44152bcb59eSGnoCiYeH     #[inline]
44252bcb59eSGnoCiYeH     pub fn add_epitem(&self, epitem: Arc<EPollItem>) {
44352bcb59eSGnoCiYeH         self.epitems.lock().push_back(epitem)
44452bcb59eSGnoCiYeH     }
44552da9a59SGnoCiYeH }
44652da9a59SGnoCiYeH 
44752da9a59SGnoCiYeH /// TTY 核心接口,不同的tty需要各自实现这个trait
44852da9a59SGnoCiYeH pub trait TtyCoreFuncs: Debug + Send + Sync {}
44952da9a59SGnoCiYeH 
45052da9a59SGnoCiYeH impl TtyOperation for TtyCore {
45152da9a59SGnoCiYeH     #[inline]
45252da9a59SGnoCiYeH     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
45352da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().open(tty);
45452da9a59SGnoCiYeH     }
45552da9a59SGnoCiYeH 
45652da9a59SGnoCiYeH     #[inline]
45752da9a59SGnoCiYeH     fn write_room(&self, tty: &TtyCoreData) -> usize {
45852da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write_room(tty);
45952da9a59SGnoCiYeH     }
46052da9a59SGnoCiYeH 
46152da9a59SGnoCiYeH     #[inline]
46252da9a59SGnoCiYeH     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
463f3b05a97SGnoCiYeH         send_to_default_serial8250_port(buf);
46452da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write(tty, buf, nr);
46552da9a59SGnoCiYeH     }
46652da9a59SGnoCiYeH 
46752da9a59SGnoCiYeH     #[inline]
46852da9a59SGnoCiYeH     fn flush_chars(&self, tty: &TtyCoreData) {
46952da9a59SGnoCiYeH         self.core().tty_driver.driver_funcs().flush_chars(tty);
47052da9a59SGnoCiYeH     }
47152da9a59SGnoCiYeH 
47252da9a59SGnoCiYeH     #[inline]
47352da9a59SGnoCiYeH     fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError> {
47452da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().put_char(tty, ch);
47552da9a59SGnoCiYeH     }
47652da9a59SGnoCiYeH 
47752da9a59SGnoCiYeH     #[inline]
47852da9a59SGnoCiYeH     fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
47952da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().install(driver, tty);
48052da9a59SGnoCiYeH     }
48152da9a59SGnoCiYeH 
48252da9a59SGnoCiYeH     #[inline]
48352da9a59SGnoCiYeH     fn start(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
48452da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().start(tty);
48552da9a59SGnoCiYeH     }
48652da9a59SGnoCiYeH 
48752da9a59SGnoCiYeH     #[inline]
48852da9a59SGnoCiYeH     fn stop(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
48952da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().stop(tty);
49052da9a59SGnoCiYeH     }
49152da9a59SGnoCiYeH 
49252da9a59SGnoCiYeH     #[inline]
49352da9a59SGnoCiYeH     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
49452da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().ioctl(tty, cmd, arg);
49552da9a59SGnoCiYeH     }
49652da9a59SGnoCiYeH 
49752da9a59SGnoCiYeH     #[inline]
49852da9a59SGnoCiYeH     fn chars_in_buffer(&self) -> usize {
49952da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().chars_in_buffer();
50052da9a59SGnoCiYeH     }
50152da9a59SGnoCiYeH 
50252da9a59SGnoCiYeH     #[inline]
50352da9a59SGnoCiYeH     fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
50452da9a59SGnoCiYeH         return self
50552da9a59SGnoCiYeH             .core()
50652da9a59SGnoCiYeH             .tty_driver
50752da9a59SGnoCiYeH             .driver_funcs()
50852da9a59SGnoCiYeH             .set_termios(tty, old_termios);
50952da9a59SGnoCiYeH     }
510*dfe53cf0SGnoCiYeH 
511*dfe53cf0SGnoCiYeH     fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
512*dfe53cf0SGnoCiYeH         self.core().tty_driver.driver_funcs().close(tty)
513*dfe53cf0SGnoCiYeH     }
51452da9a59SGnoCiYeH }
51552da9a59SGnoCiYeH 
51652da9a59SGnoCiYeH bitflags! {
51752da9a59SGnoCiYeH     pub struct TtyFlag: u32 {
51852da9a59SGnoCiYeH         /// 终端被节流
51952da9a59SGnoCiYeH         const THROTTLED		= 1 << 0;
52052da9a59SGnoCiYeH         /// 终端输入输出错误状态
52152da9a59SGnoCiYeH         const IO_ERROR		= 1 << 1;
52252da9a59SGnoCiYeH         /// 终端的其他一方已关闭
52352da9a59SGnoCiYeH         const OTHER_CLOSED	= 1 << 2;
52452da9a59SGnoCiYeH         /// 终端处于独占状态
52552da9a59SGnoCiYeH         const EXCLUSIVE		= 1 << 3;
52652da9a59SGnoCiYeH         /// 终端执行写唤醒操作
52752da9a59SGnoCiYeH         const DO_WRITE_WAKEUP	= 1 << 5;
52852da9a59SGnoCiYeH         /// 终端线路驱动程序已打开
52952da9a59SGnoCiYeH         const LDISC_OPEN		= 1 << 11;
53052da9a59SGnoCiYeH         /// 终端伪终端设备已锁定
53152da9a59SGnoCiYeH         const PTY_LOCK		= 1 << 16;
53252da9a59SGnoCiYeH         /// 终端禁用写分裂操作
53352da9a59SGnoCiYeH         const NO_WRITE_SPLIT	= 1 << 17;
53452da9a59SGnoCiYeH         /// 终端挂断(挂起)状态
53552da9a59SGnoCiYeH         const HUPPED		= 1 << 18;
53652da9a59SGnoCiYeH         /// 终端正在挂断(挂起)
53752da9a59SGnoCiYeH         const HUPPING		= 1 << 19;
53852da9a59SGnoCiYeH         /// 终端线路驱动程序正在更改
53952da9a59SGnoCiYeH         const LDISC_CHANGING	= 1 << 20;
54052da9a59SGnoCiYeH         /// 终端线路驱动程序已停止
54152da9a59SGnoCiYeH         const LDISC_HALTED	= 1 << 22;
54252da9a59SGnoCiYeH     }
543*dfe53cf0SGnoCiYeH 
544*dfe53cf0SGnoCiYeH     #[derive(Default)]
545*dfe53cf0SGnoCiYeH     pub struct TtyPacketStatus: u8 {
546*dfe53cf0SGnoCiYeH         /* Used for packet mode */
547*dfe53cf0SGnoCiYeH         const TIOCPKT_DATA		=  0;
548*dfe53cf0SGnoCiYeH         const TIOCPKT_FLUSHREAD	=  1;
549*dfe53cf0SGnoCiYeH         const TIOCPKT_FLUSHWRITE	=  2;
550*dfe53cf0SGnoCiYeH         const TIOCPKT_STOP		=  4;
551*dfe53cf0SGnoCiYeH         const TIOCPKT_START		=  8;
552*dfe53cf0SGnoCiYeH         const TIOCPKT_NOSTOP		= 16;
553*dfe53cf0SGnoCiYeH         const TIOCPKT_DOSTOP		= 32;
554*dfe53cf0SGnoCiYeH         const TIOCPKT_IOCTL		= 64;
555*dfe53cf0SGnoCiYeH     }
55652da9a59SGnoCiYeH }
55752da9a59SGnoCiYeH 
55852da9a59SGnoCiYeH #[derive(Debug, PartialEq)]
55952da9a59SGnoCiYeH pub enum EchoOperation {
56052da9a59SGnoCiYeH     /// 开始特殊操作。
56152da9a59SGnoCiYeH     Start,
56252da9a59SGnoCiYeH     /// 向后移动光标列。
56352da9a59SGnoCiYeH     MoveBackCol,
56452da9a59SGnoCiYeH     /// 设置规范模式下的列位置。
56552da9a59SGnoCiYeH     SetCanonCol,
56652da9a59SGnoCiYeH     /// 擦除制表符。
56752da9a59SGnoCiYeH     EraseTab,
56852da9a59SGnoCiYeH 
56952da9a59SGnoCiYeH     Undefined(u8),
57052da9a59SGnoCiYeH }
57152da9a59SGnoCiYeH 
57252da9a59SGnoCiYeH impl EchoOperation {
57352da9a59SGnoCiYeH     pub fn from_u8(num: u8) -> EchoOperation {
57452da9a59SGnoCiYeH         match num {
57552da9a59SGnoCiYeH             0xff => Self::Start,
57652da9a59SGnoCiYeH             0x80 => Self::MoveBackCol,
57752da9a59SGnoCiYeH             0x81 => Self::SetCanonCol,
57852da9a59SGnoCiYeH             0x82 => Self::EraseTab,
57952da9a59SGnoCiYeH             _ => Self::Undefined(num),
58052da9a59SGnoCiYeH         }
58152da9a59SGnoCiYeH     }
58252da9a59SGnoCiYeH 
58352da9a59SGnoCiYeH     pub fn to_u8(&self) -> u8 {
58452da9a59SGnoCiYeH         match *self {
58552da9a59SGnoCiYeH             EchoOperation::Start => 0xff,
58652da9a59SGnoCiYeH             EchoOperation::MoveBackCol => 0x80,
58752da9a59SGnoCiYeH             EchoOperation::SetCanonCol => 0x81,
58852da9a59SGnoCiYeH             EchoOperation::EraseTab => 0x82,
58952da9a59SGnoCiYeH             EchoOperation::Undefined(num) => num,
59052da9a59SGnoCiYeH         }
59152da9a59SGnoCiYeH     }
59252da9a59SGnoCiYeH }
59352da9a59SGnoCiYeH 
59452da9a59SGnoCiYeH pub struct TtyIoctlCmd;
59552da9a59SGnoCiYeH 
59652da9a59SGnoCiYeH #[allow(dead_code)]
59752da9a59SGnoCiYeH impl TtyIoctlCmd {
59852da9a59SGnoCiYeH     /// 获取终端参数
59952da9a59SGnoCiYeH     pub const TCGETS: u32 = 0x5401;
60052da9a59SGnoCiYeH     /// 设置终端参数
60152da9a59SGnoCiYeH     pub const TCSETS: u32 = 0x5402;
60252da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
60352da9a59SGnoCiYeH     pub const TCSETSW: u32 = 0x5403;
60452da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
60552da9a59SGnoCiYeH     pub const TCSETSF: u32 = 0x5404;
60652da9a59SGnoCiYeH     /// 获取终端参数
60752da9a59SGnoCiYeH     pub const TCGETA: u32 = 0x5405;
60852da9a59SGnoCiYeH     /// 设置终端参数
60952da9a59SGnoCiYeH     pub const TCSETA: u32 = 0x5406;
61052da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
61152da9a59SGnoCiYeH     pub const TCSETAW: u32 = 0x5407;
61252da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
61352da9a59SGnoCiYeH     pub const TCSETAF: u32 = 0x5408;
61452da9a59SGnoCiYeH     /// 发送零字节,等待所有输出完成
61552da9a59SGnoCiYeH     pub const TCSBRK: u32 = 0x5409;
61652da9a59SGnoCiYeH     /// 控制终端的流控
61752da9a59SGnoCiYeH     pub const TCXONC: u32 = 0x540A;
61852da9a59SGnoCiYeH     /// 刷新输入/输出缓冲区或者丢弃输入缓冲区
61952da9a59SGnoCiYeH     pub const TCFLSH: u32 = 0x540B;
62052da9a59SGnoCiYeH     /// 设置设备为独占模式
62152da9a59SGnoCiYeH     pub const TIOCEXCL: u32 = 0x540C;
62252da9a59SGnoCiYeH     /// 设置设备为非独占模式
62352da9a59SGnoCiYeH     pub const TIOCNXCL: u32 = 0x540D;
62452da9a59SGnoCiYeH     /// 设置当前进程的控制终端
62552da9a59SGnoCiYeH     pub const TIOCSCTTY: u32 = 0x540E;
62652da9a59SGnoCiYeH     /// 获取前台进程组
62752da9a59SGnoCiYeH     pub const TIOCGPGRP: u32 = 0x540F;
62852da9a59SGnoCiYeH     ///设置前台进程组
62952da9a59SGnoCiYeH     pub const TIOCSPGRP: u32 = 0x5410;
63052da9a59SGnoCiYeH     /// 获取输出队列的字节数
63152da9a59SGnoCiYeH     pub const TIOCOUTQ: u32 = 0x5411;
63252da9a59SGnoCiYeH     /// 模拟从终端输入字符
63352da9a59SGnoCiYeH     pub const TIOCSTI: u32 = 0x5412;
63452da9a59SGnoCiYeH     /// 获取窗口大小
63552da9a59SGnoCiYeH     pub const TIOCGWINSZ: u32 = 0x5413;
63652da9a59SGnoCiYeH     /// 设置窗口大小
63752da9a59SGnoCiYeH     pub const TIOCSWINSZ: u32 = 0x5414;
63852da9a59SGnoCiYeH     /// 获取终端控制信号的状态
63952da9a59SGnoCiYeH     pub const TIOCMGET: u32 = 0x5415;
64052da9a59SGnoCiYeH     /// 设置终端控制信号的位
64152da9a59SGnoCiYeH     pub const TIOCMBIS: u32 = 0x5416;
64252da9a59SGnoCiYeH     /// 清除终端控制信号的位
64352da9a59SGnoCiYeH     pub const TIOCMBIC: u32 = 0x5417;
64452da9a59SGnoCiYeH     /// 设置终端控制信号的状态
64552da9a59SGnoCiYeH     pub const TIOCMSET: u32 = 0x5418;
64652da9a59SGnoCiYeH     /// 获取软件载波状态
64752da9a59SGnoCiYeH     pub const TIOCGSOFTCAR: u32 = 0x5419;
64852da9a59SGnoCiYeH     /// 设置软件载波状态
64952da9a59SGnoCiYeH     pub const TIOCSSOFTCAR: u32 = 0x541A;
65052da9a59SGnoCiYeH     /// 获取输入队列的字节数
65152da9a59SGnoCiYeH     pub const FIONREAD: u32 = 0x541B;
65252da9a59SGnoCiYeH     /// Linux 特有命令
65352da9a59SGnoCiYeH     pub const TIOCLINUX: u32 = 0x541C;
65452da9a59SGnoCiYeH     /// 获取控制台设备
65552da9a59SGnoCiYeH     pub const TIOCCONS: u32 = 0x541D;
65652da9a59SGnoCiYeH     /// 获取串行设备参数
65752da9a59SGnoCiYeH     pub const TIOCGSERIAL: u32 = 0x541E;
65852da9a59SGnoCiYeH     /// 设置串行设备参数
65952da9a59SGnoCiYeH     pub const TIOCSSERIAL: u32 = 0x541F;
66052da9a59SGnoCiYeH     /// 设置套接字的报文模式
66152da9a59SGnoCiYeH     pub const TIOCPKT: u32 = 0x5420;
66252da9a59SGnoCiYeH     /// 设置非阻塞 I/O
66352da9a59SGnoCiYeH     pub const FIONBIO: u32 = 0x5421;
66452da9a59SGnoCiYeH     /// 清除控制终端
66552da9a59SGnoCiYeH     pub const TIOCNOTTY: u32 = 0x5422;
66652da9a59SGnoCiYeH     /// 设置终端线路驱动器
66752da9a59SGnoCiYeH     pub const TIOCSETD: u32 = 0x5423;
66852da9a59SGnoCiYeH     /// 获取终端线路驱动器
66952da9a59SGnoCiYeH     pub const TIOCGETD: u32 = 0x5424;
67052da9a59SGnoCiYeH     /// 发送终止条件
67152da9a59SGnoCiYeH     pub const TCSBRKP: u32 = 0x5425;
67252da9a59SGnoCiYeH     /// 开始发送零比特
67352da9a59SGnoCiYeH     pub const TIOCSBRK: u32 = 0x5427;
67452da9a59SGnoCiYeH     /// 停止发送零比特
67552da9a59SGnoCiYeH     pub const TIOCCBRK: u32 = 0x5428;
67652da9a59SGnoCiYeH     /// Return the session ID of FD
67752da9a59SGnoCiYeH     pub const TIOCGSID: u32 = 0x5429;
678*dfe53cf0SGnoCiYeH     /// 设置ptl锁标记
679*dfe53cf0SGnoCiYeH     pub const TIOCSPTLCK: u32 = 0x40045431;
680*dfe53cf0SGnoCiYeH     /// 获取ptl锁标记
681*dfe53cf0SGnoCiYeH     pub const TIOCGPTLCK: u32 = 0x80045439;
682*dfe53cf0SGnoCiYeH     /// 获取packet标记
683*dfe53cf0SGnoCiYeH     pub const TIOCGPKT: u32 = 0x80045438;
684*dfe53cf0SGnoCiYeH     /// 获取pts index
685*dfe53cf0SGnoCiYeH     pub const TIOCGPTN: u32 = 0x80045430;
68652da9a59SGnoCiYeH }
687