xref: /DragonOS/kernel/src/driver/tty/tty_device.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
120e3152eSlogin use alloc::{
220e3152eSlogin     string::{String, ToString},
320e3152eSlogin     sync::{Arc, Weak},
420e3152eSlogin };
591e9d4abSLoGin use system_error::SystemError;
6c566df45SLoGin use unified_init::macros::unified_init;
70d48c3c9Slogin 
80d48c3c9Slogin use crate::{
952da9a59SGnoCiYeH     arch::ipc::signal::Signal,
1052da9a59SGnoCiYeH     driver::{
1152da9a59SGnoCiYeH         base::{
1252da9a59SGnoCiYeH             char::CharDevice,
130cb80734SLoGin             class::Class,
1452da9a59SGnoCiYeH             device::{
1552da9a59SGnoCiYeH                 bus::Bus,
1652da9a59SGnoCiYeH                 device_number::{DeviceNumber, Major},
1752da9a59SGnoCiYeH                 device_register,
1852da9a59SGnoCiYeH                 driver::Driver,
1952da9a59SGnoCiYeH                 Device, DeviceKObjType, DeviceType, IdTable,
2052da9a59SGnoCiYeH             },
2152da9a59SGnoCiYeH             kobject::{KObject, LockedKObjectState},
2252da9a59SGnoCiYeH             kset::KSet,
2352da9a59SGnoCiYeH         },
2452da9a59SGnoCiYeH         serial::serial_init,
2552da9a59SGnoCiYeH     },
260d48c3c9Slogin     filesystem::{
2720e3152eSlogin         devfs::{devfs_register, DevFS, DeviceINode},
2852da9a59SGnoCiYeH         kernfs::KernFSInode,
2952da9a59SGnoCiYeH         vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
300d48c3c9Slogin     },
31c566df45SLoGin     init::initcall::INITCALL_DEVICE,
32*dfe53cf0SGnoCiYeH     libs::{
33*dfe53cf0SGnoCiYeH         rwlock::{RwLock, RwLockWriteGuard},
34*dfe53cf0SGnoCiYeH         spinlock::SpinLockGuard,
35*dfe53cf0SGnoCiYeH     },
3652da9a59SGnoCiYeH     mm::VirtAddr,
3752bcb59eSGnoCiYeH     net::event_poll::{EPollItem, EventPoll},
3852da9a59SGnoCiYeH     process::ProcessManager,
3952bcb59eSGnoCiYeH     syscall::user_access::{UserBufferReader, UserBufferWriter},
400d48c3c9Slogin };
410d48c3c9Slogin 
4252da9a59SGnoCiYeH use super::{
4359fdb447SLoGin     kthread::tty_flush_thread_init,
44*dfe53cf0SGnoCiYeH     pty::unix98pty::ptmx_open,
450cb80734SLoGin     sysfs::sys_class_tty_instance,
4652da9a59SGnoCiYeH     termios::WindowSize,
4752da9a59SGnoCiYeH     tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
48*dfe53cf0SGnoCiYeH     tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
4952da9a59SGnoCiYeH     tty_job_control::TtyJobCtrlManager,
5052da9a59SGnoCiYeH     virtual_terminal::vty_init,
5152da9a59SGnoCiYeH };
520d48c3c9Slogin 
5352da9a59SGnoCiYeH #[derive(Debug)]
5452da9a59SGnoCiYeH pub struct InnerTtyDevice {
5552da9a59SGnoCiYeH     /// 当前设备所述的kset
5652da9a59SGnoCiYeH     kset: Option<Arc<KSet>>,
5752da9a59SGnoCiYeH     parent_kobj: Option<Weak<dyn KObject>>,
5852da9a59SGnoCiYeH     /// 当前设备所述的总线
5952da9a59SGnoCiYeH     bus: Option<Weak<dyn Bus>>,
6052da9a59SGnoCiYeH     inode: Option<Arc<KernFSInode>>,
6152da9a59SGnoCiYeH     driver: Option<Weak<dyn Driver>>,
6252da9a59SGnoCiYeH     can_match: bool,
6352da9a59SGnoCiYeH 
6452da9a59SGnoCiYeH     metadata: Metadata,
6520e3152eSlogin }
6620e3152eSlogin 
6752da9a59SGnoCiYeH impl InnerTtyDevice {
6852da9a59SGnoCiYeH     pub fn new() -> Self {
6952da9a59SGnoCiYeH         Self {
7052da9a59SGnoCiYeH             kset: None,
7152da9a59SGnoCiYeH             parent_kobj: None,
7252da9a59SGnoCiYeH             bus: None,
7352da9a59SGnoCiYeH             inode: None,
7452da9a59SGnoCiYeH             driver: None,
7552da9a59SGnoCiYeH             can_match: false,
7652da9a59SGnoCiYeH             metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
7752da9a59SGnoCiYeH         }
7852da9a59SGnoCiYeH     }
79*dfe53cf0SGnoCiYeH 
80*dfe53cf0SGnoCiYeH     pub fn metadata_mut(&mut self) -> &mut Metadata {
81*dfe53cf0SGnoCiYeH         &mut self.metadata
82*dfe53cf0SGnoCiYeH     }
83*dfe53cf0SGnoCiYeH }
84*dfe53cf0SGnoCiYeH 
85*dfe53cf0SGnoCiYeH #[derive(Debug, PartialEq)]
86*dfe53cf0SGnoCiYeH pub enum TtyType {
87*dfe53cf0SGnoCiYeH     Tty,
88*dfe53cf0SGnoCiYeH     Pty(PtyType),
89*dfe53cf0SGnoCiYeH }
90*dfe53cf0SGnoCiYeH 
91*dfe53cf0SGnoCiYeH #[derive(Debug, PartialEq)]
92*dfe53cf0SGnoCiYeH pub enum PtyType {
93*dfe53cf0SGnoCiYeH     Ptm,
94*dfe53cf0SGnoCiYeH     Pts,
9552da9a59SGnoCiYeH }
9652da9a59SGnoCiYeH 
970d48c3c9Slogin #[derive(Debug)]
9852da9a59SGnoCiYeH #[cast_to([sync] Device)]
990d48c3c9Slogin pub struct TtyDevice {
100*dfe53cf0SGnoCiYeH     name: String,
10152da9a59SGnoCiYeH     id_table: IdTable,
102*dfe53cf0SGnoCiYeH     tty_type: TtyType,
10352da9a59SGnoCiYeH     inner: RwLock<InnerTtyDevice>,
10452da9a59SGnoCiYeH     kobj_state: LockedKObjectState,
10520e3152eSlogin     /// TTY所属的文件系统
10620e3152eSlogin     fs: RwLock<Weak<DevFS>>,
1070d48c3c9Slogin }
1080d48c3c9Slogin 
1090d48c3c9Slogin impl TtyDevice {
110*dfe53cf0SGnoCiYeH     pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
11152da9a59SGnoCiYeH         let dev_num = id_table.device_number();
11252da9a59SGnoCiYeH         let dev = TtyDevice {
11352da9a59SGnoCiYeH             name,
11452da9a59SGnoCiYeH             id_table,
11552da9a59SGnoCiYeH             inner: RwLock::new(InnerTtyDevice::new()),
11652da9a59SGnoCiYeH             kobj_state: LockedKObjectState::new(None),
1170d48c3c9Slogin             fs: RwLock::new(Weak::default()),
118*dfe53cf0SGnoCiYeH             tty_type,
11952da9a59SGnoCiYeH         };
12052da9a59SGnoCiYeH 
12152da9a59SGnoCiYeH         dev.inner.write().metadata.raw_dev = dev_num;
12252da9a59SGnoCiYeH 
12352da9a59SGnoCiYeH         Arc::new(dev)
12452da9a59SGnoCiYeH     }
125*dfe53cf0SGnoCiYeH 
126*dfe53cf0SGnoCiYeH     pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
127*dfe53cf0SGnoCiYeH         self.inner.write()
128*dfe53cf0SGnoCiYeH     }
1290d48c3c9Slogin }
1300d48c3c9Slogin 
13152da9a59SGnoCiYeH impl IndexNode for TtyDevice {
13252da9a59SGnoCiYeH     fn open(
1330d48c3c9Slogin         &self,
134*dfe53cf0SGnoCiYeH         mut data: SpinLockGuard<FilePrivateData>,
13552da9a59SGnoCiYeH         mode: &crate::filesystem::vfs::file::FileMode,
13652da9a59SGnoCiYeH     ) -> Result<(), SystemError> {
137*dfe53cf0SGnoCiYeH         if self.tty_type == TtyType::Pty(PtyType::Ptm) {
138*dfe53cf0SGnoCiYeH             if let FilePrivateData::Tty(_) = &*data {
139*dfe53cf0SGnoCiYeH                 return Ok(());
140*dfe53cf0SGnoCiYeH             }
141*dfe53cf0SGnoCiYeH             return ptmx_open(data, mode);
142*dfe53cf0SGnoCiYeH         }
14352da9a59SGnoCiYeH         let dev_num = self.metadata()?.raw_dev;
14452da9a59SGnoCiYeH 
145*dfe53cf0SGnoCiYeH         let (index, driver) =
146*dfe53cf0SGnoCiYeH             TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
147*dfe53cf0SGnoCiYeH 
148*dfe53cf0SGnoCiYeH         let tty = TtyDriver::open_tty(index, driver)?;
14952da9a59SGnoCiYeH 
15052da9a59SGnoCiYeH         // 设置privdata
15152da9a59SGnoCiYeH         *data = FilePrivateData::Tty(TtyFilePrivateData {
15252da9a59SGnoCiYeH             tty: tty.clone(),
15352da9a59SGnoCiYeH             mode: *mode,
15452da9a59SGnoCiYeH         });
15552da9a59SGnoCiYeH 
15652da9a59SGnoCiYeH         let ret = tty.open(tty.core());
157b5b571e0SLoGin         if let Err(err) = ret {
15852da9a59SGnoCiYeH             if err == SystemError::ENOSYS {
15952da9a59SGnoCiYeH                 return Err(SystemError::ENODEV);
1600d48c3c9Slogin             }
16152da9a59SGnoCiYeH             return Err(err);
16252da9a59SGnoCiYeH         }
16352da9a59SGnoCiYeH 
16452da9a59SGnoCiYeH         let driver = tty.core().driver();
16552da9a59SGnoCiYeH         // 考虑noctty(当前tty)
16652da9a59SGnoCiYeH         if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0)
16752da9a59SGnoCiYeH             || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1)
16852da9a59SGnoCiYeH             || (driver.tty_driver_type() == TtyDriverType::Pty
16952da9a59SGnoCiYeH                 && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
17052da9a59SGnoCiYeH         {
17152da9a59SGnoCiYeH             let pcb = ProcessManager::current_pcb();
17252bcb59eSGnoCiYeH             let pcb_tty = pcb.sig_info_irqsave().tty();
17352da9a59SGnoCiYeH             if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
17452da9a59SGnoCiYeH                 TtyJobCtrlManager::proc_set_tty(tty);
17552da9a59SGnoCiYeH             }
17652da9a59SGnoCiYeH         }
17752da9a59SGnoCiYeH 
17852da9a59SGnoCiYeH         Ok(())
17952da9a59SGnoCiYeH     }
18052da9a59SGnoCiYeH 
18152da9a59SGnoCiYeH     fn read_at(
18252da9a59SGnoCiYeH         &self,
18352da9a59SGnoCiYeH         _offset: usize,
18452da9a59SGnoCiYeH         len: usize,
18552da9a59SGnoCiYeH         buf: &mut [u8],
186*dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
18752da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
188*dfe53cf0SGnoCiYeH         let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
189*dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
19052da9a59SGnoCiYeH         } else {
191676b8ef6SMork             return Err(SystemError::EIO);
19252da9a59SGnoCiYeH         };
19352da9a59SGnoCiYeH 
194*dfe53cf0SGnoCiYeH         drop(data);
195*dfe53cf0SGnoCiYeH 
19652da9a59SGnoCiYeH         let ld = tty.ldisc();
19752da9a59SGnoCiYeH         let mut offset = 0;
19852da9a59SGnoCiYeH         let mut cookie = false;
19952da9a59SGnoCiYeH         loop {
20052da9a59SGnoCiYeH             let mut size = if len > buf.len() { buf.len() } else { len };
20152da9a59SGnoCiYeH             size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?;
20252da9a59SGnoCiYeH             // 没有更多数据
20352da9a59SGnoCiYeH             if size == 0 {
20452da9a59SGnoCiYeH                 break;
2050d48c3c9Slogin             }
20620e3152eSlogin 
20752da9a59SGnoCiYeH             offset += size;
20852da9a59SGnoCiYeH 
20952da9a59SGnoCiYeH             // 缓冲区写满
21052da9a59SGnoCiYeH             if offset >= len {
21152da9a59SGnoCiYeH                 break;
21220e3152eSlogin             }
21320e3152eSlogin 
21452da9a59SGnoCiYeH             // 没有更多数据
21552da9a59SGnoCiYeH             if !cookie {
21652da9a59SGnoCiYeH                 break;
21720e3152eSlogin             }
21820e3152eSlogin         }
21920e3152eSlogin 
22052da9a59SGnoCiYeH         return Ok(offset);
22120e3152eSlogin     }
22220e3152eSlogin 
22352da9a59SGnoCiYeH     fn write_at(
22452da9a59SGnoCiYeH         &self,
22552da9a59SGnoCiYeH         _offset: usize,
22652da9a59SGnoCiYeH         len: usize,
22752da9a59SGnoCiYeH         buf: &[u8],
228*dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
22952da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
23052da9a59SGnoCiYeH         let mut count = len;
231*dfe53cf0SGnoCiYeH         let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
232*dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
23352da9a59SGnoCiYeH         } else {
23452da9a59SGnoCiYeH             return Err(SystemError::EIO);
23552da9a59SGnoCiYeH         };
236*dfe53cf0SGnoCiYeH         drop(data);
23752da9a59SGnoCiYeH         let ld = tty.ldisc();
23852da9a59SGnoCiYeH         let core = tty.core();
23952da9a59SGnoCiYeH         let mut chunk = 2048;
24052da9a59SGnoCiYeH         if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) {
24152da9a59SGnoCiYeH             chunk = 65536;
24252da9a59SGnoCiYeH         }
24352da9a59SGnoCiYeH         chunk = chunk.min(count);
24452da9a59SGnoCiYeH 
24552da9a59SGnoCiYeH         let pcb = ProcessManager::current_pcb();
24652da9a59SGnoCiYeH         let mut written = 0;
24752da9a59SGnoCiYeH         loop {
24852da9a59SGnoCiYeH             // 至少需要写多少
24952da9a59SGnoCiYeH             let size = chunk.min(count);
25052da9a59SGnoCiYeH 
25152da9a59SGnoCiYeH             // 将数据从buf拷贝到writebuf
25252da9a59SGnoCiYeH 
25352bcb59eSGnoCiYeH             let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
25452da9a59SGnoCiYeH 
25552da9a59SGnoCiYeH             written += ret;
25652da9a59SGnoCiYeH             count -= ret;
25752da9a59SGnoCiYeH 
25852da9a59SGnoCiYeH             if count == 0 {
25952da9a59SGnoCiYeH                 break;
26052da9a59SGnoCiYeH             }
26152da9a59SGnoCiYeH 
26252bcb59eSGnoCiYeH             if pcb.sig_info_irqsave().sig_pending().has_pending() {
26352da9a59SGnoCiYeH                 return Err(SystemError::ERESTARTSYS);
26420e3152eSlogin             }
26520e3152eSlogin         }
26652da9a59SGnoCiYeH 
26752da9a59SGnoCiYeH         if written > 0 {
26852da9a59SGnoCiYeH             // todo: 更新时间
26952da9a59SGnoCiYeH         }
27052da9a59SGnoCiYeH 
27152da9a59SGnoCiYeH         Ok(written)
27252da9a59SGnoCiYeH     }
27352da9a59SGnoCiYeH 
27452da9a59SGnoCiYeH     fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
27552da9a59SGnoCiYeH         todo!()
27652da9a59SGnoCiYeH     }
27752da9a59SGnoCiYeH 
27852da9a59SGnoCiYeH     fn as_any_ref(&self) -> &dyn core::any::Any {
279*dfe53cf0SGnoCiYeH         self
28052da9a59SGnoCiYeH     }
28152da9a59SGnoCiYeH 
28252da9a59SGnoCiYeH     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
28352da9a59SGnoCiYeH         todo!()
28452da9a59SGnoCiYeH     }
28552da9a59SGnoCiYeH 
28652da9a59SGnoCiYeH     fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
28752da9a59SGnoCiYeH         Ok(self.inner.read().metadata.clone())
28852da9a59SGnoCiYeH     }
28952da9a59SGnoCiYeH 
290*dfe53cf0SGnoCiYeH     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
291*dfe53cf0SGnoCiYeH         let mut guard = self.inner_write();
292*dfe53cf0SGnoCiYeH         guard.metadata = metadata.clone();
293*dfe53cf0SGnoCiYeH 
29452da9a59SGnoCiYeH         Ok(())
29552da9a59SGnoCiYeH     }
29652da9a59SGnoCiYeH 
297*dfe53cf0SGnoCiYeH     fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
298*dfe53cf0SGnoCiYeH         let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
299*dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
300*dfe53cf0SGnoCiYeH         } else {
301*dfe53cf0SGnoCiYeH             return Err(SystemError::EIO);
302*dfe53cf0SGnoCiYeH         };
303*dfe53cf0SGnoCiYeH         drop(data);
304*dfe53cf0SGnoCiYeH         tty.close(tty.clone())
305*dfe53cf0SGnoCiYeH     }
306*dfe53cf0SGnoCiYeH 
30752da9a59SGnoCiYeH     fn resize(&self, _len: usize) -> Result<(), SystemError> {
30852da9a59SGnoCiYeH         Ok(())
30952da9a59SGnoCiYeH     }
31052da9a59SGnoCiYeH 
31152da9a59SGnoCiYeH     fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
31252da9a59SGnoCiYeH         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
313*dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
31452da9a59SGnoCiYeH         } else {
31552da9a59SGnoCiYeH             return Err(SystemError::EIO);
31652da9a59SGnoCiYeH         };
31752da9a59SGnoCiYeH 
31852da9a59SGnoCiYeH         match cmd {
31952da9a59SGnoCiYeH             TtyIoctlCmd::TIOCSETD
32052da9a59SGnoCiYeH             | TtyIoctlCmd::TIOCSBRK
32152da9a59SGnoCiYeH             | TtyIoctlCmd::TIOCCBRK
32252da9a59SGnoCiYeH             | TtyIoctlCmd::TCSBRK
32352da9a59SGnoCiYeH             | TtyIoctlCmd::TCSBRKP => {
32452da9a59SGnoCiYeH                 TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
32552da9a59SGnoCiYeH                 if cmd != TtyIoctlCmd::TIOCCBRK {
32652da9a59SGnoCiYeH                     todo!()
32752da9a59SGnoCiYeH                 }
32852da9a59SGnoCiYeH             }
32952bcb59eSGnoCiYeH             EventPoll::ADD_EPOLLITEM => {
33052bcb59eSGnoCiYeH                 let _ = UserBufferReader::new(
33152bcb59eSGnoCiYeH                     arg as *const Arc<EPollItem>,
33252bcb59eSGnoCiYeH                     core::mem::size_of::<Arc<EPollItem>>(),
33352bcb59eSGnoCiYeH                     false,
33452bcb59eSGnoCiYeH                 )?;
33552bcb59eSGnoCiYeH                 let epitem = unsafe { &*(arg as *const Arc<EPollItem>) };
33652bcb59eSGnoCiYeH 
33752bcb59eSGnoCiYeH                 let core = tty.core();
33852bcb59eSGnoCiYeH 
33952bcb59eSGnoCiYeH                 core.add_epitem(epitem.clone());
34052bcb59eSGnoCiYeH 
34152bcb59eSGnoCiYeH                 return Ok(0);
34252bcb59eSGnoCiYeH             }
34352da9a59SGnoCiYeH             _ => {}
34452da9a59SGnoCiYeH         }
34552da9a59SGnoCiYeH 
34652da9a59SGnoCiYeH         match cmd {
34752da9a59SGnoCiYeH             TtyIoctlCmd::TIOCGWINSZ => {
34852da9a59SGnoCiYeH                 let core = tty.core();
34952da9a59SGnoCiYeH                 let winsize = *core.window_size();
35052da9a59SGnoCiYeH 
35152da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
35252da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<WindowSize>(),
35352da9a59SGnoCiYeH                     core::mem::size_of::<WindowSize>(),
35452da9a59SGnoCiYeH                     true,
35552da9a59SGnoCiYeH                 )?;
35652da9a59SGnoCiYeH 
35752da9a59SGnoCiYeH                 let err = user_writer.copy_one_to_user(&winsize, 0);
35852da9a59SGnoCiYeH                 if err.is_err() {
35952da9a59SGnoCiYeH                     return Err(SystemError::EFAULT);
36052da9a59SGnoCiYeH                 }
36152da9a59SGnoCiYeH                 return Ok(0);
36252da9a59SGnoCiYeH             }
36352da9a59SGnoCiYeH             _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
36452da9a59SGnoCiYeH                 Ok(_) => {
36552da9a59SGnoCiYeH                     return Ok(0);
36652da9a59SGnoCiYeH                 }
36752da9a59SGnoCiYeH                 Err(e) => {
36852da9a59SGnoCiYeH                     if e != SystemError::ENOIOCTLCMD {
36952da9a59SGnoCiYeH                         return Err(e);
37052da9a59SGnoCiYeH                     }
37152da9a59SGnoCiYeH                 }
37252da9a59SGnoCiYeH             },
37352da9a59SGnoCiYeH         }
37452da9a59SGnoCiYeH 
37552da9a59SGnoCiYeH         match tty.ioctl(tty.clone(), cmd, arg) {
37652da9a59SGnoCiYeH             Ok(_) => {
37752da9a59SGnoCiYeH                 return Ok(0);
37852da9a59SGnoCiYeH             }
37952da9a59SGnoCiYeH             Err(e) => {
38052da9a59SGnoCiYeH                 if e != SystemError::ENOIOCTLCMD {
38152da9a59SGnoCiYeH                     return Err(e);
38252da9a59SGnoCiYeH                 }
38352da9a59SGnoCiYeH             }
38452da9a59SGnoCiYeH         }
38552da9a59SGnoCiYeH         tty.ldisc().ioctl(tty, cmd, arg)?;
38652da9a59SGnoCiYeH 
38752da9a59SGnoCiYeH         Ok(0)
38820e3152eSlogin     }
38952bcb59eSGnoCiYeH 
39052bcb59eSGnoCiYeH     fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
39152bcb59eSGnoCiYeH         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
39252bcb59eSGnoCiYeH             (tty_priv.tty.clone(), tty_priv.mode)
39352bcb59eSGnoCiYeH         } else {
39452bcb59eSGnoCiYeH             return Err(SystemError::EIO);
39552bcb59eSGnoCiYeH         };
39652bcb59eSGnoCiYeH 
39752bcb59eSGnoCiYeH         tty.ldisc().poll(tty)
39852bcb59eSGnoCiYeH     }
3990d48c3c9Slogin }
4000d48c3c9Slogin 
4010d48c3c9Slogin impl DeviceINode for TtyDevice {
4020d48c3c9Slogin     fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
4030d48c3c9Slogin         *self.fs.write() = fs;
4040d48c3c9Slogin     }
4050d48c3c9Slogin }
4060d48c3c9Slogin 
40752da9a59SGnoCiYeH impl KObject for TtyDevice {
4080d48c3c9Slogin     fn as_any_ref(&self) -> &dyn core::any::Any {
4090d48c3c9Slogin         self
4100d48c3c9Slogin     }
4110d48c3c9Slogin 
41252da9a59SGnoCiYeH     fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
41352da9a59SGnoCiYeH         self.inner.write().inode = inode;
4140d48c3c9Slogin     }
41520e3152eSlogin 
41652da9a59SGnoCiYeH     fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
41752da9a59SGnoCiYeH         self.inner.read().inode.clone()
41820e3152eSlogin     }
41920e3152eSlogin 
42052da9a59SGnoCiYeH     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
42152da9a59SGnoCiYeH         self.inner.read().parent_kobj.clone()
42252da9a59SGnoCiYeH     }
42352da9a59SGnoCiYeH 
42452da9a59SGnoCiYeH     fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
42552da9a59SGnoCiYeH         self.inner.write().parent_kobj = parent
42652da9a59SGnoCiYeH     }
42752da9a59SGnoCiYeH 
42852da9a59SGnoCiYeH     fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
42952da9a59SGnoCiYeH         self.inner.read().kset.clone()
43052da9a59SGnoCiYeH     }
43152da9a59SGnoCiYeH 
43252da9a59SGnoCiYeH     fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
43352da9a59SGnoCiYeH         self.inner.write().kset = kset
43452da9a59SGnoCiYeH     }
43552da9a59SGnoCiYeH 
43652da9a59SGnoCiYeH     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
43752da9a59SGnoCiYeH         Some(&DeviceKObjType)
43852da9a59SGnoCiYeH     }
43952da9a59SGnoCiYeH 
44052da9a59SGnoCiYeH     fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {}
44152da9a59SGnoCiYeH 
44252da9a59SGnoCiYeH     fn name(&self) -> alloc::string::String {
44352da9a59SGnoCiYeH         self.name.to_string()
44452da9a59SGnoCiYeH     }
44552da9a59SGnoCiYeH 
44652da9a59SGnoCiYeH     fn set_name(&self, _name: alloc::string::String) {
44752da9a59SGnoCiYeH         // self.name = name
44852da9a59SGnoCiYeH     }
44952da9a59SGnoCiYeH 
45052da9a59SGnoCiYeH     fn kobj_state(
45152da9a59SGnoCiYeH         &self,
45252da9a59SGnoCiYeH     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
45352da9a59SGnoCiYeH         self.kobj_state.read()
45452da9a59SGnoCiYeH     }
45552da9a59SGnoCiYeH 
45652da9a59SGnoCiYeH     fn kobj_state_mut(
45752da9a59SGnoCiYeH         &self,
45852da9a59SGnoCiYeH     ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
45952da9a59SGnoCiYeH         self.kobj_state.write()
46052da9a59SGnoCiYeH     }
46152da9a59SGnoCiYeH 
46252da9a59SGnoCiYeH     fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) {
46352da9a59SGnoCiYeH         *self.kobj_state.write() = state
46452da9a59SGnoCiYeH     }
46552da9a59SGnoCiYeH }
46652da9a59SGnoCiYeH 
46752da9a59SGnoCiYeH impl Device for TtyDevice {
46852da9a59SGnoCiYeH     fn dev_type(&self) -> crate::driver::base::device::DeviceType {
46952da9a59SGnoCiYeH         DeviceType::Char
47052da9a59SGnoCiYeH     }
47152da9a59SGnoCiYeH 
47252da9a59SGnoCiYeH     fn id_table(&self) -> crate::driver::base::device::IdTable {
47352da9a59SGnoCiYeH         self.id_table.clone()
47452da9a59SGnoCiYeH     }
47552da9a59SGnoCiYeH 
4760cb80734SLoGin     fn bus(&self) -> Option<Weak<dyn Bus>> {
4770cb80734SLoGin         self.inner.read().bus.clone()
4780cb80734SLoGin     }
4790cb80734SLoGin 
48052da9a59SGnoCiYeH     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
48152da9a59SGnoCiYeH         self.inner.write().bus = bus
48252da9a59SGnoCiYeH     }
48352da9a59SGnoCiYeH 
4844256da7fSLoGin     fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
4850cb80734SLoGin         // do nothing
4860cb80734SLoGin     }
4870cb80734SLoGin 
4880cb80734SLoGin     fn class(&self) -> Option<Arc<dyn Class>> {
4890cb80734SLoGin         sys_class_tty_instance()
4900cb80734SLoGin             .cloned()
4910cb80734SLoGin             .map(|x| x as Arc<dyn Class>)
49252da9a59SGnoCiYeH     }
49352da9a59SGnoCiYeH 
49452da9a59SGnoCiYeH     fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> {
49552da9a59SGnoCiYeH         self.inner.read().driver.clone()?.upgrade()
49652da9a59SGnoCiYeH     }
49752da9a59SGnoCiYeH 
49852da9a59SGnoCiYeH     fn set_driver(
49952da9a59SGnoCiYeH         &self,
50052da9a59SGnoCiYeH         driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>,
50152da9a59SGnoCiYeH     ) {
50252da9a59SGnoCiYeH         self.inner.write().driver = driver
50352da9a59SGnoCiYeH     }
50452da9a59SGnoCiYeH 
50552da9a59SGnoCiYeH     fn is_dead(&self) -> bool {
50652da9a59SGnoCiYeH         false
50752da9a59SGnoCiYeH     }
50852da9a59SGnoCiYeH 
50952da9a59SGnoCiYeH     fn can_match(&self) -> bool {
51052da9a59SGnoCiYeH         self.inner.read().can_match
51152da9a59SGnoCiYeH     }
51252da9a59SGnoCiYeH 
51352da9a59SGnoCiYeH     fn set_can_match(&self, can_match: bool) {
51452da9a59SGnoCiYeH         self.inner.write().can_match = can_match
51552da9a59SGnoCiYeH     }
51652da9a59SGnoCiYeH 
51752da9a59SGnoCiYeH     fn state_synced(&self) -> bool {
51852da9a59SGnoCiYeH         true
51952da9a59SGnoCiYeH     }
52052da9a59SGnoCiYeH }
52152da9a59SGnoCiYeH 
52252da9a59SGnoCiYeH impl CharDevice for TtyDevice {
52352da9a59SGnoCiYeH     fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> {
52452da9a59SGnoCiYeH         todo!()
52552da9a59SGnoCiYeH     }
52652da9a59SGnoCiYeH 
52752da9a59SGnoCiYeH     fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> {
52852da9a59SGnoCiYeH         todo!()
52920e3152eSlogin     }
53020e3152eSlogin 
53120e3152eSlogin     fn sync(&self) -> Result<(), SystemError> {
53252da9a59SGnoCiYeH         todo!()
53311110997Shanjiezhou     }
53420e3152eSlogin }
53520e3152eSlogin 
53652da9a59SGnoCiYeH #[derive(Debug, Clone)]
53752da9a59SGnoCiYeH pub struct TtyFilePrivateData {
538*dfe53cf0SGnoCiYeH     pub tty: Arc<TtyCore>,
539*dfe53cf0SGnoCiYeH     pub mode: FileMode,
540*dfe53cf0SGnoCiYeH }
541*dfe53cf0SGnoCiYeH 
542*dfe53cf0SGnoCiYeH impl TtyFilePrivateData {
543*dfe53cf0SGnoCiYeH     pub fn tty(&self) -> Arc<TtyCore> {
544*dfe53cf0SGnoCiYeH         self.tty.clone()
545*dfe53cf0SGnoCiYeH     }
54620e3152eSlogin }
54720e3152eSlogin 
54852da9a59SGnoCiYeH /// 初始化tty设备和console子设备
549c566df45SLoGin #[unified_init(INITCALL_DEVICE)]
55052da9a59SGnoCiYeH #[inline(never)]
55120e3152eSlogin pub fn tty_init() -> Result<(), SystemError> {
55252da9a59SGnoCiYeH     let tty = TtyDevice::new(
553*dfe53cf0SGnoCiYeH         "tty0".to_string(),
55452da9a59SGnoCiYeH         IdTable::new(
55552da9a59SGnoCiYeH             String::from("tty0"),
55652da9a59SGnoCiYeH             Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
55752da9a59SGnoCiYeH         ),
558*dfe53cf0SGnoCiYeH         TtyType::Tty,
55952da9a59SGnoCiYeH     );
56020e3152eSlogin 
56152da9a59SGnoCiYeH     let console = TtyDevice::new(
562*dfe53cf0SGnoCiYeH         "console".to_string(),
56352da9a59SGnoCiYeH         IdTable::new(
56452da9a59SGnoCiYeH             String::from("console"),
56552da9a59SGnoCiYeH             Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
56652da9a59SGnoCiYeH         ),
567*dfe53cf0SGnoCiYeH         TtyType::Tty,
56852da9a59SGnoCiYeH     );
56920e3152eSlogin 
57052da9a59SGnoCiYeH     // 注册tty设备
57152da9a59SGnoCiYeH     // CharDevOps::cdev_add(
57252da9a59SGnoCiYeH     //     tty.clone() as Arc<dyn CharDevice>,
57352da9a59SGnoCiYeH     // IdTable::new(
57452da9a59SGnoCiYeH     //     String::from("tty0"),
57552da9a59SGnoCiYeH     //     Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 0)),
57652da9a59SGnoCiYeH     // ),
57752da9a59SGnoCiYeH     //     1,
57852da9a59SGnoCiYeH     // )?;
57920e3152eSlogin 
58052da9a59SGnoCiYeH     // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 0), 1, "/dev/tty")?;
58120e3152eSlogin 
58252da9a59SGnoCiYeH     // 注册console设备
58352da9a59SGnoCiYeH     // CharDevOps::cdev_add(
58452da9a59SGnoCiYeH     //     console.clone() as Arc<dyn CharDevice>,
58552da9a59SGnoCiYeH     //     IdTable::new(
58652da9a59SGnoCiYeH     //         String::from("console"),
58752da9a59SGnoCiYeH     //         Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
58852da9a59SGnoCiYeH     //     ),
58952da9a59SGnoCiYeH     //     1,
59052da9a59SGnoCiYeH     // )?;
59120e3152eSlogin 
59252da9a59SGnoCiYeH     // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 1), 1, "/dev/tty")?;
59352da9a59SGnoCiYeH 
59452da9a59SGnoCiYeH     // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
59552da9a59SGnoCiYeH     device_register(tty.clone())?;
59652da9a59SGnoCiYeH     device_register(console.clone())?;
597*dfe53cf0SGnoCiYeH     devfs_register(&tty.name.clone(), tty)?;
598*dfe53cf0SGnoCiYeH     devfs_register(&console.name.clone(), console)?;
59920e3152eSlogin 
600a03c4f9dSLoGin     serial_init()?;
60159fdb447SLoGin 
60259fdb447SLoGin     tty_flush_thread_init();
60352da9a59SGnoCiYeH     return vty_init();
6040d48c3c9Slogin }
605