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, 37*415e14e9Slaokengwt 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 { 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 } 79dfe53cf0SGnoCiYeH 80dfe53cf0SGnoCiYeH 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 { 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 126dfe53cf0SGnoCiYeH pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> { 127dfe53cf0SGnoCiYeH self.inner.write() 128dfe53cf0SGnoCiYeH } 1290d48c3c9Slogin } 1300d48c3c9Slogin 13152da9a59SGnoCiYeH impl IndexNode for TtyDevice { 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 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 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 27452da9a59SGnoCiYeH fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 27552da9a59SGnoCiYeH todo!() 27652da9a59SGnoCiYeH } 27752da9a59SGnoCiYeH 27852da9a59SGnoCiYeH fn as_any_ref(&self) -> &dyn core::any::Any { 279dfe53cf0SGnoCiYeH 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 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 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 30752da9a59SGnoCiYeH fn resize(&self, _len: usize) -> Result<(), SystemError> { 30852da9a59SGnoCiYeH Ok(()) 30952da9a59SGnoCiYeH } 31052da9a59SGnoCiYeH 311*415e14e9Slaokengwt fn kernel_ioctl( 312*415e14e9Slaokengwt &self, 313*415e14e9Slaokengwt arg: Arc<dyn KernelIoctlData>, 314*415e14e9Slaokengwt data: &FilePrivateData, 315*415e14e9Slaokengwt ) -> Result<usize, SystemError> { 316*415e14e9Slaokengwt let epitem = arg 317*415e14e9Slaokengwt .arc_any() 318*415e14e9Slaokengwt .downcast::<EPollItem>() 319*415e14e9Slaokengwt .map_err(|_| SystemError::EFAULT)?; 320*415e14e9Slaokengwt 321*415e14e9Slaokengwt let _ = UserBufferReader::new( 322*415e14e9Slaokengwt &epitem as *const Arc<EPollItem>, 323*415e14e9Slaokengwt core::mem::size_of::<Arc<EPollItem>>(), 324*415e14e9Slaokengwt false, 325*415e14e9Slaokengwt )?; 326*415e14e9Slaokengwt 327*415e14e9Slaokengwt let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { 328*415e14e9Slaokengwt (tty_priv.tty(), tty_priv.mode) 329*415e14e9Slaokengwt } else { 330*415e14e9Slaokengwt return Err(SystemError::EIO); 331*415e14e9Slaokengwt }; 332*415e14e9Slaokengwt 333*415e14e9Slaokengwt let core = tty.core(); 334*415e14e9Slaokengwt 335*415e14e9Slaokengwt core.add_epitem(epitem.clone()); 336*415e14e9Slaokengwt 337*415e14e9Slaokengwt return Ok(0); 338*415e14e9Slaokengwt } 339*415e14e9Slaokengwt 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 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 { 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 { 4400d48c3c9Slogin fn as_any_ref(&self) -> &dyn core::any::Any { 4410d48c3c9Slogin self 4420d48c3c9Slogin } 4430d48c3c9Slogin 44452da9a59SGnoCiYeH fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 44552da9a59SGnoCiYeH self.inner.write().inode = inode; 4460d48c3c9Slogin } 44720e3152eSlogin 44852da9a59SGnoCiYeH fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 44952da9a59SGnoCiYeH self.inner.read().inode.clone() 45020e3152eSlogin } 45120e3152eSlogin 45252da9a59SGnoCiYeH fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 45352da9a59SGnoCiYeH self.inner.read().parent_kobj.clone() 45452da9a59SGnoCiYeH } 45552da9a59SGnoCiYeH 45652da9a59SGnoCiYeH fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) { 45752da9a59SGnoCiYeH self.inner.write().parent_kobj = parent 45852da9a59SGnoCiYeH } 45952da9a59SGnoCiYeH 46052da9a59SGnoCiYeH fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 46152da9a59SGnoCiYeH self.inner.read().kset.clone() 46252da9a59SGnoCiYeH } 46352da9a59SGnoCiYeH 46452da9a59SGnoCiYeH fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) { 46552da9a59SGnoCiYeH self.inner.write().kset = kset 46652da9a59SGnoCiYeH } 46752da9a59SGnoCiYeH 46852da9a59SGnoCiYeH fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 46952da9a59SGnoCiYeH Some(&DeviceKObjType) 47052da9a59SGnoCiYeH } 47152da9a59SGnoCiYeH 47252da9a59SGnoCiYeH fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {} 47352da9a59SGnoCiYeH 47452da9a59SGnoCiYeH fn name(&self) -> alloc::string::String { 47552da9a59SGnoCiYeH self.name.to_string() 47652da9a59SGnoCiYeH } 47752da9a59SGnoCiYeH 47852da9a59SGnoCiYeH fn set_name(&self, _name: alloc::string::String) { 47952da9a59SGnoCiYeH // self.name = name 48052da9a59SGnoCiYeH } 48152da9a59SGnoCiYeH 48252da9a59SGnoCiYeH fn kobj_state( 48352da9a59SGnoCiYeH &self, 48452da9a59SGnoCiYeH ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 48552da9a59SGnoCiYeH self.kobj_state.read() 48652da9a59SGnoCiYeH } 48752da9a59SGnoCiYeH 48852da9a59SGnoCiYeH fn kobj_state_mut( 48952da9a59SGnoCiYeH &self, 49052da9a59SGnoCiYeH ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 49152da9a59SGnoCiYeH self.kobj_state.write() 49252da9a59SGnoCiYeH } 49352da9a59SGnoCiYeH 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 { 50052da9a59SGnoCiYeH fn dev_type(&self) -> crate::driver::base::device::DeviceType { 50152da9a59SGnoCiYeH DeviceType::Char 50252da9a59SGnoCiYeH } 50352da9a59SGnoCiYeH 50452da9a59SGnoCiYeH fn id_table(&self) -> crate::driver::base::device::IdTable { 50552da9a59SGnoCiYeH self.id_table.clone() 50652da9a59SGnoCiYeH } 50752da9a59SGnoCiYeH 5080cb80734SLoGin fn bus(&self) -> Option<Weak<dyn Bus>> { 5090cb80734SLoGin self.inner.read().bus.clone() 5100cb80734SLoGin } 5110cb80734SLoGin 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 5164256da7fSLoGin fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) { 5170cb80734SLoGin // do nothing 5180cb80734SLoGin } 5190cb80734SLoGin 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 52652da9a59SGnoCiYeH fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> { 52752da9a59SGnoCiYeH self.inner.read().driver.clone()?.upgrade() 52852da9a59SGnoCiYeH } 52952da9a59SGnoCiYeH 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 53752da9a59SGnoCiYeH fn is_dead(&self) -> bool { 53852da9a59SGnoCiYeH false 53952da9a59SGnoCiYeH } 54052da9a59SGnoCiYeH 54152da9a59SGnoCiYeH fn can_match(&self) -> bool { 54252da9a59SGnoCiYeH self.inner.read().can_match 54352da9a59SGnoCiYeH } 54452da9a59SGnoCiYeH 54552da9a59SGnoCiYeH fn set_can_match(&self, can_match: bool) { 54652da9a59SGnoCiYeH self.inner.write().can_match = can_match 54752da9a59SGnoCiYeH } 54852da9a59SGnoCiYeH 54952da9a59SGnoCiYeH fn state_synced(&self) -> bool { 55052da9a59SGnoCiYeH true 55152da9a59SGnoCiYeH } 55252da9a59SGnoCiYeH } 55352da9a59SGnoCiYeH 55452da9a59SGnoCiYeH impl CharDevice for TtyDevice { 55552da9a59SGnoCiYeH fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> { 55652da9a59SGnoCiYeH todo!() 55752da9a59SGnoCiYeH } 55852da9a59SGnoCiYeH 55952da9a59SGnoCiYeH fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> { 56052da9a59SGnoCiYeH todo!() 56120e3152eSlogin } 56220e3152eSlogin 56320e3152eSlogin fn sync(&self) -> Result<(), SystemError> { 56452da9a59SGnoCiYeH todo!() 56511110997Shanjiezhou } 56620e3152eSlogin } 56720e3152eSlogin 56852da9a59SGnoCiYeH #[derive(Debug, Clone)] 56952da9a59SGnoCiYeH pub struct TtyFilePrivateData { 570dfe53cf0SGnoCiYeH pub tty: Arc<TtyCore>, 571dfe53cf0SGnoCiYeH pub mode: FileMode, 572dfe53cf0SGnoCiYeH } 573dfe53cf0SGnoCiYeH 574dfe53cf0SGnoCiYeH impl TtyFilePrivateData { 575dfe53cf0SGnoCiYeH pub fn tty(&self) -> Arc<TtyCore> { 576dfe53cf0SGnoCiYeH self.tty.clone() 577dfe53cf0SGnoCiYeH } 57820e3152eSlogin } 57920e3152eSlogin 58052da9a59SGnoCiYeH /// 初始化tty设备和console子设备 581c566df45SLoGin #[unified_init(INITCALL_DEVICE)] 58252da9a59SGnoCiYeH #[inline(never)] 58320e3152eSlogin pub fn tty_init() -> Result<(), SystemError> { 58452da9a59SGnoCiYeH let tty = TtyDevice::new( 585dfe53cf0SGnoCiYeH "tty0".to_string(), 58652da9a59SGnoCiYeH IdTable::new( 58752da9a59SGnoCiYeH String::from("tty0"), 58852da9a59SGnoCiYeH Some(DeviceNumber::new(Major::TTY_MAJOR, 0)), 58952da9a59SGnoCiYeH ), 590dfe53cf0SGnoCiYeH TtyType::Tty, 59152da9a59SGnoCiYeH ); 59220e3152eSlogin 59352da9a59SGnoCiYeH let console = TtyDevice::new( 594dfe53cf0SGnoCiYeH "console".to_string(), 59552da9a59SGnoCiYeH IdTable::new( 59652da9a59SGnoCiYeH String::from("console"), 59752da9a59SGnoCiYeH Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), 59852da9a59SGnoCiYeH ), 599dfe53cf0SGnoCiYeH TtyType::Tty, 60052da9a59SGnoCiYeH ); 60120e3152eSlogin 60252da9a59SGnoCiYeH // 注册tty设备 60352da9a59SGnoCiYeH // CharDevOps::cdev_add( 60452da9a59SGnoCiYeH // tty.clone() as Arc<dyn CharDevice>, 60552da9a59SGnoCiYeH // IdTable::new( 60652da9a59SGnoCiYeH // String::from("tty0"), 60752da9a59SGnoCiYeH // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 0)), 60852da9a59SGnoCiYeH // ), 60952da9a59SGnoCiYeH // 1, 61052da9a59SGnoCiYeH // )?; 61120e3152eSlogin 61252da9a59SGnoCiYeH // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 0), 1, "/dev/tty")?; 61320e3152eSlogin 61452da9a59SGnoCiYeH // 注册console设备 61552da9a59SGnoCiYeH // CharDevOps::cdev_add( 61652da9a59SGnoCiYeH // console.clone() as Arc<dyn CharDevice>, 61752da9a59SGnoCiYeH // IdTable::new( 61852da9a59SGnoCiYeH // String::from("console"), 61952da9a59SGnoCiYeH // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), 62052da9a59SGnoCiYeH // ), 62152da9a59SGnoCiYeH // 1, 62252da9a59SGnoCiYeH // )?; 62320e3152eSlogin 62452da9a59SGnoCiYeH // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 1), 1, "/dev/tty")?; 62552da9a59SGnoCiYeH 62652da9a59SGnoCiYeH // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面 62752da9a59SGnoCiYeH device_register(tty.clone())?; 62852da9a59SGnoCiYeH device_register(console.clone())?; 629dfe53cf0SGnoCiYeH devfs_register(&tty.name.clone(), tty)?; 630dfe53cf0SGnoCiYeH devfs_register(&console.name.clone(), console)?; 63120e3152eSlogin 632a03c4f9dSLoGin serial_init()?; 63359fdb447SLoGin 63459fdb447SLoGin tty_flush_thread_init(); 63552da9a59SGnoCiYeH return vty_init(); 6360d48c3c9Slogin } 637