xref: /DragonOS/kernel/src/driver/tty/tty_device.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
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,
32dfe53cf0SGnoCiYeH     libs::{
33dfe53cf0SGnoCiYeH         rwlock::{RwLock, RwLockWriteGuard},
34dfe53cf0SGnoCiYeH         spinlock::SpinLockGuard,
35dfe53cf0SGnoCiYeH     },
3652da9a59SGnoCiYeH     mm::VirtAddr,
37415e14e9Slaokengwt     net::event_poll::{EPollItem, KernelIoctlData},
3852da9a59SGnoCiYeH     process::ProcessManager,
3952bcb59eSGnoCiYeH     syscall::user_access::{UserBufferReader, UserBufferWriter},
400d48c3c9Slogin };
410d48c3c9Slogin 
4252da9a59SGnoCiYeH use super::{
4359fdb447SLoGin     kthread::tty_flush_thread_init,
44dfe53cf0SGnoCiYeH     pty::unix98pty::ptmx_open,
450cb80734SLoGin     sysfs::sys_class_tty_instance,
4652da9a59SGnoCiYeH     termios::WindowSize,
4752da9a59SGnoCiYeH     tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
48dfe53cf0SGnoCiYeH     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 {
new() -> Self6852da9a59SGnoCiYeH     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     }
79dfe53cf0SGnoCiYeH 
metadata_mut(&mut self) -> &mut Metadata80dfe53cf0SGnoCiYeH     pub fn metadata_mut(&mut self) -> &mut Metadata {
81dfe53cf0SGnoCiYeH         &mut self.metadata
82dfe53cf0SGnoCiYeH     }
83dfe53cf0SGnoCiYeH }
84dfe53cf0SGnoCiYeH 
85dfe53cf0SGnoCiYeH #[derive(Debug, PartialEq)]
86dfe53cf0SGnoCiYeH pub enum TtyType {
87dfe53cf0SGnoCiYeH     Tty,
88dfe53cf0SGnoCiYeH     Pty(PtyType),
89dfe53cf0SGnoCiYeH }
90dfe53cf0SGnoCiYeH 
91dfe53cf0SGnoCiYeH #[derive(Debug, PartialEq)]
92dfe53cf0SGnoCiYeH pub enum PtyType {
93dfe53cf0SGnoCiYeH     Ptm,
94dfe53cf0SGnoCiYeH     Pts,
9552da9a59SGnoCiYeH }
9652da9a59SGnoCiYeH 
970d48c3c9Slogin #[derive(Debug)]
9852da9a59SGnoCiYeH #[cast_to([sync] Device)]
990d48c3c9Slogin pub struct TtyDevice {
100dfe53cf0SGnoCiYeH     name: String,
10152da9a59SGnoCiYeH     id_table: IdTable,
102dfe53cf0SGnoCiYeH     tty_type: TtyType,
10352da9a59SGnoCiYeH     inner: RwLock<InnerTtyDevice>,
10452da9a59SGnoCiYeH     kobj_state: LockedKObjectState,
10520e3152eSlogin     /// TTY所属的文件系统
10620e3152eSlogin     fs: RwLock<Weak<DevFS>>,
1070d48c3c9Slogin }
1080d48c3c9Slogin 
1090d48c3c9Slogin impl TtyDevice {
new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice>110dfe53cf0SGnoCiYeH     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()),
118dfe53cf0SGnoCiYeH             tty_type,
11952da9a59SGnoCiYeH         };
12052da9a59SGnoCiYeH 
12152da9a59SGnoCiYeH         dev.inner.write().metadata.raw_dev = dev_num;
12252da9a59SGnoCiYeH 
12352da9a59SGnoCiYeH         Arc::new(dev)
12452da9a59SGnoCiYeH     }
125dfe53cf0SGnoCiYeH 
inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice>126dfe53cf0SGnoCiYeH     pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
127dfe53cf0SGnoCiYeH         self.inner.write()
128dfe53cf0SGnoCiYeH     }
1290d48c3c9Slogin }
1300d48c3c9Slogin 
13152da9a59SGnoCiYeH impl IndexNode for TtyDevice {
open( &self, mut data: SpinLockGuard<FilePrivateData>, mode: &crate::filesystem::vfs::file::FileMode, ) -> Result<(), SystemError>13252da9a59SGnoCiYeH     fn open(
1330d48c3c9Slogin         &self,
134dfe53cf0SGnoCiYeH         mut data: SpinLockGuard<FilePrivateData>,
13552da9a59SGnoCiYeH         mode: &crate::filesystem::vfs::file::FileMode,
13652da9a59SGnoCiYeH     ) -> Result<(), SystemError> {
137dfe53cf0SGnoCiYeH         if let FilePrivateData::Tty(_) = &*data {
138dfe53cf0SGnoCiYeH             return Ok(());
139dfe53cf0SGnoCiYeH         }
1409365e801SGnoCiYeH         if self.tty_type == TtyType::Pty(PtyType::Ptm) {
141dfe53cf0SGnoCiYeH             return ptmx_open(data, mode);
142dfe53cf0SGnoCiYeH         }
14352da9a59SGnoCiYeH         let dev_num = self.metadata()?.raw_dev;
14452da9a59SGnoCiYeH 
145dfe53cf0SGnoCiYeH         let (index, driver) =
146dfe53cf0SGnoCiYeH             TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
147dfe53cf0SGnoCiYeH 
148dfe53cf0SGnoCiYeH         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 
read_at( &self, _offset: usize, len: usize, buf: &mut [u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, system_error::SystemError>18152da9a59SGnoCiYeH     fn read_at(
18252da9a59SGnoCiYeH         &self,
18352da9a59SGnoCiYeH         _offset: usize,
18452da9a59SGnoCiYeH         len: usize,
18552da9a59SGnoCiYeH         buf: &mut [u8],
186dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
18752da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
188dfe53cf0SGnoCiYeH         let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
189dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
19052da9a59SGnoCiYeH         } else {
191676b8ef6SMork             return Err(SystemError::EIO);
19252da9a59SGnoCiYeH         };
19352da9a59SGnoCiYeH 
194dfe53cf0SGnoCiYeH         drop(data);
195dfe53cf0SGnoCiYeH 
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 
write_at( &self, _offset: usize, len: usize, buf: &[u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, system_error::SystemError>22352da9a59SGnoCiYeH     fn write_at(
22452da9a59SGnoCiYeH         &self,
22552da9a59SGnoCiYeH         _offset: usize,
22652da9a59SGnoCiYeH         len: usize,
22752da9a59SGnoCiYeH         buf: &[u8],
228dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
22952da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
23052da9a59SGnoCiYeH         let mut count = len;
231dfe53cf0SGnoCiYeH         let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
232dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
23352da9a59SGnoCiYeH         } else {
23452da9a59SGnoCiYeH             return Err(SystemError::EIO);
23552da9a59SGnoCiYeH         };
236dfe53cf0SGnoCiYeH         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 
fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem>27452da9a59SGnoCiYeH     fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
27552da9a59SGnoCiYeH         todo!()
27652da9a59SGnoCiYeH     }
27752da9a59SGnoCiYeH 
as_any_ref(&self) -> &dyn core::any::Any27852da9a59SGnoCiYeH     fn as_any_ref(&self) -> &dyn core::any::Any {
279dfe53cf0SGnoCiYeH         self
28052da9a59SGnoCiYeH     }
28152da9a59SGnoCiYeH 
list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError>28252da9a59SGnoCiYeH     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
28352da9a59SGnoCiYeH         todo!()
28452da9a59SGnoCiYeH     }
28552da9a59SGnoCiYeH 
metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError>28652da9a59SGnoCiYeH     fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
28752da9a59SGnoCiYeH         Ok(self.inner.read().metadata.clone())
28852da9a59SGnoCiYeH     }
28952da9a59SGnoCiYeH 
set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>290dfe53cf0SGnoCiYeH     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
291dfe53cf0SGnoCiYeH         let mut guard = self.inner_write();
292dfe53cf0SGnoCiYeH         guard.metadata = metadata.clone();
293dfe53cf0SGnoCiYeH 
29452da9a59SGnoCiYeH         Ok(())
29552da9a59SGnoCiYeH     }
29652da9a59SGnoCiYeH 
close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>297dfe53cf0SGnoCiYeH     fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
298dfe53cf0SGnoCiYeH         let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
299dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
300dfe53cf0SGnoCiYeH         } else {
301dfe53cf0SGnoCiYeH             return Err(SystemError::EIO);
302dfe53cf0SGnoCiYeH         };
303dfe53cf0SGnoCiYeH         drop(data);
304dfe53cf0SGnoCiYeH         tty.close(tty.clone())
305dfe53cf0SGnoCiYeH     }
306dfe53cf0SGnoCiYeH 
resize(&self, _len: usize) -> Result<(), SystemError>30752da9a59SGnoCiYeH     fn resize(&self, _len: usize) -> Result<(), SystemError> {
30852da9a59SGnoCiYeH         Ok(())
30952da9a59SGnoCiYeH     }
31052da9a59SGnoCiYeH 
kernel_ioctl( &self, arg: Arc<dyn KernelIoctlData>, data: &FilePrivateData, ) -> Result<usize, SystemError>311415e14e9Slaokengwt     fn kernel_ioctl(
312415e14e9Slaokengwt         &self,
313415e14e9Slaokengwt         arg: Arc<dyn KernelIoctlData>,
314415e14e9Slaokengwt         data: &FilePrivateData,
315415e14e9Slaokengwt     ) -> Result<usize, SystemError> {
316415e14e9Slaokengwt         let epitem = arg
317415e14e9Slaokengwt             .arc_any()
318415e14e9Slaokengwt             .downcast::<EPollItem>()
319415e14e9Slaokengwt             .map_err(|_| SystemError::EFAULT)?;
320415e14e9Slaokengwt 
321415e14e9Slaokengwt         let _ = UserBufferReader::new(
322415e14e9Slaokengwt             &epitem as *const Arc<EPollItem>,
323415e14e9Slaokengwt             core::mem::size_of::<Arc<EPollItem>>(),
324415e14e9Slaokengwt             false,
325415e14e9Slaokengwt         )?;
326415e14e9Slaokengwt 
327415e14e9Slaokengwt         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
328415e14e9Slaokengwt             (tty_priv.tty(), tty_priv.mode)
329415e14e9Slaokengwt         } else {
330415e14e9Slaokengwt             return Err(SystemError::EIO);
331415e14e9Slaokengwt         };
332415e14e9Slaokengwt 
333415e14e9Slaokengwt         let core = tty.core();
334415e14e9Slaokengwt 
335415e14e9Slaokengwt         core.add_epitem(epitem.clone());
336415e14e9Slaokengwt 
337415e14e9Slaokengwt         return Ok(0);
338415e14e9Slaokengwt     }
339415e14e9Slaokengwt 
ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError>34052da9a59SGnoCiYeH     fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
34152da9a59SGnoCiYeH         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
342dfe53cf0SGnoCiYeH             (tty_priv.tty(), tty_priv.mode)
34352da9a59SGnoCiYeH         } else {
34452da9a59SGnoCiYeH             return Err(SystemError::EIO);
34552da9a59SGnoCiYeH         };
34652da9a59SGnoCiYeH 
34752da9a59SGnoCiYeH         match cmd {
34852da9a59SGnoCiYeH             TtyIoctlCmd::TIOCSETD
34952da9a59SGnoCiYeH             | TtyIoctlCmd::TIOCSBRK
35052da9a59SGnoCiYeH             | TtyIoctlCmd::TIOCCBRK
35152da9a59SGnoCiYeH             | TtyIoctlCmd::TCSBRK
35252da9a59SGnoCiYeH             | TtyIoctlCmd::TCSBRKP => {
35352da9a59SGnoCiYeH                 TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
35452da9a59SGnoCiYeH                 if cmd != TtyIoctlCmd::TIOCCBRK {
35552da9a59SGnoCiYeH                     todo!()
35652da9a59SGnoCiYeH                 }
35752da9a59SGnoCiYeH             }
35852da9a59SGnoCiYeH             _ => {}
35952da9a59SGnoCiYeH         }
36052da9a59SGnoCiYeH 
36152da9a59SGnoCiYeH         match cmd {
36252da9a59SGnoCiYeH             TtyIoctlCmd::TIOCGWINSZ => {
36352da9a59SGnoCiYeH                 let core = tty.core();
36452da9a59SGnoCiYeH                 let winsize = *core.window_size();
36552da9a59SGnoCiYeH 
36652da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
36752da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<WindowSize>(),
36852da9a59SGnoCiYeH                     core::mem::size_of::<WindowSize>(),
36952da9a59SGnoCiYeH                     true,
37052da9a59SGnoCiYeH                 )?;
37152da9a59SGnoCiYeH 
37252da9a59SGnoCiYeH                 let err = user_writer.copy_one_to_user(&winsize, 0);
37352da9a59SGnoCiYeH                 if err.is_err() {
37452da9a59SGnoCiYeH                     return Err(SystemError::EFAULT);
37552da9a59SGnoCiYeH                 }
37652da9a59SGnoCiYeH                 return Ok(0);
37752da9a59SGnoCiYeH             }
3789365e801SGnoCiYeH             TtyIoctlCmd::TIOCSWINSZ => {
3799365e801SGnoCiYeH                 let reader = UserBufferReader::new(
3809365e801SGnoCiYeH                     arg as *const (),
3819365e801SGnoCiYeH                     core::mem::size_of::<WindowSize>(),
3829365e801SGnoCiYeH                     true,
3839365e801SGnoCiYeH                 )?;
3849365e801SGnoCiYeH 
3859365e801SGnoCiYeH                 let user_winsize = reader.read_one_from_user::<WindowSize>(0)?;
3869365e801SGnoCiYeH 
3879365e801SGnoCiYeH                 let ret = tty.resize(tty.clone(), *user_winsize);
3889365e801SGnoCiYeH 
3899365e801SGnoCiYeH                 if ret != Err(SystemError::ENOSYS) {
3909365e801SGnoCiYeH                     return ret.map(|_| 0);
3919365e801SGnoCiYeH                 } else {
3929365e801SGnoCiYeH                     return tty.tty_do_resize(*user_winsize).map(|_| 0);
3939365e801SGnoCiYeH                 }
3949365e801SGnoCiYeH             }
39552da9a59SGnoCiYeH             _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
39652da9a59SGnoCiYeH                 Ok(_) => {
39752da9a59SGnoCiYeH                     return Ok(0);
39852da9a59SGnoCiYeH                 }
39952da9a59SGnoCiYeH                 Err(e) => {
40052da9a59SGnoCiYeH                     if e != SystemError::ENOIOCTLCMD {
40152da9a59SGnoCiYeH                         return Err(e);
40252da9a59SGnoCiYeH                     }
40352da9a59SGnoCiYeH                 }
40452da9a59SGnoCiYeH             },
40552da9a59SGnoCiYeH         }
40652da9a59SGnoCiYeH 
40752da9a59SGnoCiYeH         match tty.ioctl(tty.clone(), cmd, arg) {
40852da9a59SGnoCiYeH             Ok(_) => {
40952da9a59SGnoCiYeH                 return Ok(0);
41052da9a59SGnoCiYeH             }
41152da9a59SGnoCiYeH             Err(e) => {
41252da9a59SGnoCiYeH                 if e != SystemError::ENOIOCTLCMD {
41352da9a59SGnoCiYeH                     return Err(e);
41452da9a59SGnoCiYeH                 }
41552da9a59SGnoCiYeH             }
41652da9a59SGnoCiYeH         }
41752da9a59SGnoCiYeH         tty.ldisc().ioctl(tty, cmd, arg)?;
41852da9a59SGnoCiYeH 
41952da9a59SGnoCiYeH         Ok(0)
42020e3152eSlogin     }
42152bcb59eSGnoCiYeH 
poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError>42252bcb59eSGnoCiYeH     fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
42352bcb59eSGnoCiYeH         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
42452bcb59eSGnoCiYeH             (tty_priv.tty.clone(), tty_priv.mode)
42552bcb59eSGnoCiYeH         } else {
42652bcb59eSGnoCiYeH             return Err(SystemError::EIO);
42752bcb59eSGnoCiYeH         };
42852bcb59eSGnoCiYeH 
42952bcb59eSGnoCiYeH         tty.ldisc().poll(tty)
43052bcb59eSGnoCiYeH     }
4310d48c3c9Slogin }
4320d48c3c9Slogin 
4330d48c3c9Slogin impl DeviceINode for TtyDevice {
set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>)4340d48c3c9Slogin     fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
4350d48c3c9Slogin         *self.fs.write() = fs;
4360d48c3c9Slogin     }
4370d48c3c9Slogin }
4380d48c3c9Slogin 
43952da9a59SGnoCiYeH impl KObject for TtyDevice {
as_any_ref(&self) -> &dyn core::any::Any4400d48c3c9Slogin     fn as_any_ref(&self) -> &dyn core::any::Any {
4410d48c3c9Slogin         self
4420d48c3c9Slogin     }
4430d48c3c9Slogin 
set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>)44452da9a59SGnoCiYeH     fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
44552da9a59SGnoCiYeH         self.inner.write().inode = inode;
4460d48c3c9Slogin     }
44720e3152eSlogin 
inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>>44852da9a59SGnoCiYeH     fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
44952da9a59SGnoCiYeH         self.inner.read().inode.clone()
45020e3152eSlogin     }
45120e3152eSlogin 
parent(&self) -> Option<alloc::sync::Weak<dyn KObject>>45252da9a59SGnoCiYeH     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
45352da9a59SGnoCiYeH         self.inner.read().parent_kobj.clone()
45452da9a59SGnoCiYeH     }
45552da9a59SGnoCiYeH 
set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>)45652da9a59SGnoCiYeH     fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
45752da9a59SGnoCiYeH         self.inner.write().parent_kobj = parent
45852da9a59SGnoCiYeH     }
45952da9a59SGnoCiYeH 
kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>>46052da9a59SGnoCiYeH     fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
46152da9a59SGnoCiYeH         self.inner.read().kset.clone()
46252da9a59SGnoCiYeH     }
46352da9a59SGnoCiYeH 
set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>)46452da9a59SGnoCiYeH     fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
46552da9a59SGnoCiYeH         self.inner.write().kset = kset
46652da9a59SGnoCiYeH     }
46752da9a59SGnoCiYeH 
kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType>46852da9a59SGnoCiYeH     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
46952da9a59SGnoCiYeH         Some(&DeviceKObjType)
47052da9a59SGnoCiYeH     }
47152da9a59SGnoCiYeH 
set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>)47252da9a59SGnoCiYeH     fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {}
47352da9a59SGnoCiYeH 
name(&self) -> alloc::string::String47452da9a59SGnoCiYeH     fn name(&self) -> alloc::string::String {
47552da9a59SGnoCiYeH         self.name.to_string()
47652da9a59SGnoCiYeH     }
47752da9a59SGnoCiYeH 
set_name(&self, _name: alloc::string::String)47852da9a59SGnoCiYeH     fn set_name(&self, _name: alloc::string::String) {
47952da9a59SGnoCiYeH         // self.name = name
48052da9a59SGnoCiYeH     }
48152da9a59SGnoCiYeH 
kobj_state( &self, ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState>48252da9a59SGnoCiYeH     fn kobj_state(
48352da9a59SGnoCiYeH         &self,
48452da9a59SGnoCiYeH     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
48552da9a59SGnoCiYeH         self.kobj_state.read()
48652da9a59SGnoCiYeH     }
48752da9a59SGnoCiYeH 
kobj_state_mut( &self, ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState>48852da9a59SGnoCiYeH     fn kobj_state_mut(
48952da9a59SGnoCiYeH         &self,
49052da9a59SGnoCiYeH     ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
49152da9a59SGnoCiYeH         self.kobj_state.write()
49252da9a59SGnoCiYeH     }
49352da9a59SGnoCiYeH 
set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState)49452da9a59SGnoCiYeH     fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) {
49552da9a59SGnoCiYeH         *self.kobj_state.write() = state
49652da9a59SGnoCiYeH     }
49752da9a59SGnoCiYeH }
49852da9a59SGnoCiYeH 
49952da9a59SGnoCiYeH impl Device for TtyDevice {
dev_type(&self) -> crate::driver::base::device::DeviceType50052da9a59SGnoCiYeH     fn dev_type(&self) -> crate::driver::base::device::DeviceType {
50152da9a59SGnoCiYeH         DeviceType::Char
50252da9a59SGnoCiYeH     }
50352da9a59SGnoCiYeH 
id_table(&self) -> crate::driver::base::device::IdTable50452da9a59SGnoCiYeH     fn id_table(&self) -> crate::driver::base::device::IdTable {
50552da9a59SGnoCiYeH         self.id_table.clone()
50652da9a59SGnoCiYeH     }
50752da9a59SGnoCiYeH 
bus(&self) -> Option<Weak<dyn Bus>>5080cb80734SLoGin     fn bus(&self) -> Option<Weak<dyn Bus>> {
5090cb80734SLoGin         self.inner.read().bus.clone()
5100cb80734SLoGin     }
5110cb80734SLoGin 
set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>)51252da9a59SGnoCiYeH     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
51352da9a59SGnoCiYeH         self.inner.write().bus = bus
51452da9a59SGnoCiYeH     }
51552da9a59SGnoCiYeH 
set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>)5164256da7fSLoGin     fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
5170cb80734SLoGin         // do nothing
5180cb80734SLoGin     }
5190cb80734SLoGin 
class(&self) -> Option<Arc<dyn Class>>5200cb80734SLoGin     fn class(&self) -> Option<Arc<dyn Class>> {
5210cb80734SLoGin         sys_class_tty_instance()
5220cb80734SLoGin             .cloned()
5230cb80734SLoGin             .map(|x| x as Arc<dyn Class>)
52452da9a59SGnoCiYeH     }
52552da9a59SGnoCiYeH 
driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>>52652da9a59SGnoCiYeH     fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> {
52752da9a59SGnoCiYeH         self.inner.read().driver.clone()?.upgrade()
52852da9a59SGnoCiYeH     }
52952da9a59SGnoCiYeH 
set_driver( &self, driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>, )53052da9a59SGnoCiYeH     fn set_driver(
53152da9a59SGnoCiYeH         &self,
53252da9a59SGnoCiYeH         driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>,
53352da9a59SGnoCiYeH     ) {
53452da9a59SGnoCiYeH         self.inner.write().driver = driver
53552da9a59SGnoCiYeH     }
53652da9a59SGnoCiYeH 
is_dead(&self) -> bool53752da9a59SGnoCiYeH     fn is_dead(&self) -> bool {
53852da9a59SGnoCiYeH         false
53952da9a59SGnoCiYeH     }
54052da9a59SGnoCiYeH 
can_match(&self) -> bool54152da9a59SGnoCiYeH     fn can_match(&self) -> bool {
54252da9a59SGnoCiYeH         self.inner.read().can_match
54352da9a59SGnoCiYeH     }
54452da9a59SGnoCiYeH 
set_can_match(&self, can_match: bool)54552da9a59SGnoCiYeH     fn set_can_match(&self, can_match: bool) {
54652da9a59SGnoCiYeH         self.inner.write().can_match = can_match
54752da9a59SGnoCiYeH     }
54852da9a59SGnoCiYeH 
state_synced(&self) -> bool54952da9a59SGnoCiYeH     fn state_synced(&self) -> bool {
55052da9a59SGnoCiYeH         true
55152da9a59SGnoCiYeH     }
552*28fe4ad2S黄铭涛 
dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>553*28fe4ad2S黄铭涛     fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>> {
554*28fe4ad2S黄铭涛         None
555*28fe4ad2S黄铭涛     }
556*28fe4ad2S黄铭涛 
set_dev_parent( &self, _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>, )557*28fe4ad2S黄铭涛     fn set_dev_parent(
558*28fe4ad2S黄铭涛         &self,
559*28fe4ad2S黄铭涛         _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>,
560*28fe4ad2S黄铭涛     ) {
561*28fe4ad2S黄铭涛         todo!()
562*28fe4ad2S黄铭涛     }
56352da9a59SGnoCiYeH }
56452da9a59SGnoCiYeH 
56552da9a59SGnoCiYeH impl CharDevice for TtyDevice {
read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError>56652da9a59SGnoCiYeH     fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> {
56752da9a59SGnoCiYeH         todo!()
56852da9a59SGnoCiYeH     }
56952da9a59SGnoCiYeH 
write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError>57052da9a59SGnoCiYeH     fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> {
57152da9a59SGnoCiYeH         todo!()
57220e3152eSlogin     }
57320e3152eSlogin 
sync(&self) -> Result<(), SystemError>57420e3152eSlogin     fn sync(&self) -> Result<(), SystemError> {
57552da9a59SGnoCiYeH         todo!()
57611110997Shanjiezhou     }
57720e3152eSlogin }
57820e3152eSlogin 
57952da9a59SGnoCiYeH #[derive(Debug, Clone)]
58052da9a59SGnoCiYeH pub struct TtyFilePrivateData {
581dfe53cf0SGnoCiYeH     pub tty: Arc<TtyCore>,
582dfe53cf0SGnoCiYeH     pub mode: FileMode,
583dfe53cf0SGnoCiYeH }
584dfe53cf0SGnoCiYeH 
585dfe53cf0SGnoCiYeH impl TtyFilePrivateData {
tty(&self) -> Arc<TtyCore>586dfe53cf0SGnoCiYeH     pub fn tty(&self) -> Arc<TtyCore> {
587dfe53cf0SGnoCiYeH         self.tty.clone()
588dfe53cf0SGnoCiYeH     }
58920e3152eSlogin }
59020e3152eSlogin 
59152da9a59SGnoCiYeH /// 初始化tty设备和console子设备
592c566df45SLoGin #[unified_init(INITCALL_DEVICE)]
59352da9a59SGnoCiYeH #[inline(never)]
tty_init() -> Result<(), SystemError>59420e3152eSlogin pub fn tty_init() -> Result<(), SystemError> {
59552da9a59SGnoCiYeH     let tty = TtyDevice::new(
596dfe53cf0SGnoCiYeH         "tty0".to_string(),
59752da9a59SGnoCiYeH         IdTable::new(
59852da9a59SGnoCiYeH             String::from("tty0"),
59952da9a59SGnoCiYeH             Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
60052da9a59SGnoCiYeH         ),
601dfe53cf0SGnoCiYeH         TtyType::Tty,
60252da9a59SGnoCiYeH     );
60320e3152eSlogin 
60452da9a59SGnoCiYeH     let console = TtyDevice::new(
605dfe53cf0SGnoCiYeH         "console".to_string(),
60652da9a59SGnoCiYeH         IdTable::new(
60752da9a59SGnoCiYeH             String::from("console"),
60852da9a59SGnoCiYeH             Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
60952da9a59SGnoCiYeH         ),
610dfe53cf0SGnoCiYeH         TtyType::Tty,
61152da9a59SGnoCiYeH     );
61220e3152eSlogin 
61352da9a59SGnoCiYeH     // 注册tty设备
61452da9a59SGnoCiYeH     // CharDevOps::cdev_add(
61552da9a59SGnoCiYeH     //     tty.clone() as Arc<dyn CharDevice>,
61652da9a59SGnoCiYeH     // IdTable::new(
61752da9a59SGnoCiYeH     //     String::from("tty0"),
61852da9a59SGnoCiYeH     //     Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 0)),
61952da9a59SGnoCiYeH     // ),
62052da9a59SGnoCiYeH     //     1,
62152da9a59SGnoCiYeH     // )?;
62220e3152eSlogin 
62352da9a59SGnoCiYeH     // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 0), 1, "/dev/tty")?;
62420e3152eSlogin 
62552da9a59SGnoCiYeH     // 注册console设备
62652da9a59SGnoCiYeH     // CharDevOps::cdev_add(
62752da9a59SGnoCiYeH     //     console.clone() as Arc<dyn CharDevice>,
62852da9a59SGnoCiYeH     //     IdTable::new(
62952da9a59SGnoCiYeH     //         String::from("console"),
63052da9a59SGnoCiYeH     //         Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
63152da9a59SGnoCiYeH     //     ),
63252da9a59SGnoCiYeH     //     1,
63352da9a59SGnoCiYeH     // )?;
63420e3152eSlogin 
63552da9a59SGnoCiYeH     // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 1), 1, "/dev/tty")?;
63652da9a59SGnoCiYeH 
63752da9a59SGnoCiYeH     // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
63852da9a59SGnoCiYeH     device_register(tty.clone())?;
63952da9a59SGnoCiYeH     device_register(console.clone())?;
640dfe53cf0SGnoCiYeH     devfs_register(&tty.name.clone(), tty)?;
641dfe53cf0SGnoCiYeH     devfs_register(&console.name.clone(), console)?;
64220e3152eSlogin 
643a03c4f9dSLoGin     serial_init()?;
64459fdb447SLoGin 
64559fdb447SLoGin     tty_flush_thread_init();
64652da9a59SGnoCiYeH     return vty_init();
6470d48c3c9Slogin }
648