1 use alloc::{ 2 string::{String, ToString}, 3 sync::Arc, 4 }; 5 use system_error::SystemError; 6 use unified_init::macros::unified_init; 7 8 use crate::{ 9 driver::base::device::{ 10 device_number::{DeviceNumber, Major}, 11 device_register, IdTable, 12 }, 13 filesystem::devfs::devfs_register, 14 init::initcall::INITCALL_DEVICE, 15 libs::lazy_init::Lazy, 16 mm::VirtAddr, 17 syscall::user_access::{UserBufferReader, UserBufferWriter}, 18 }; 19 20 use self::unix98pty::{Unix98PtyDriverInner, NR_UNIX98_PTY_MAX}; 21 22 use super::{ 23 termios::{ControlMode, InputMode, LocalMode, OutputMode, TTY_STD_TERMIOS}, 24 tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyPacketStatus}, 25 tty_device::{TtyDevice, TtyType}, 26 tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TTY_DRIVERS}, 27 tty_port::{DefaultTtyPort, TtyPort}, 28 }; 29 30 pub mod unix98pty; 31 32 static PTM_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new(); 33 static PTS_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new(); 34 35 pub(super) fn ptm_driver() -> Arc<TtyDriver> { 36 PTM_DRIVER.ensure(); 37 PTM_DRIVER.get().clone() 38 } 39 40 pub(super) fn pts_driver() -> Arc<TtyDriver> { 41 PTS_DRIVER.ensure(); 42 PTS_DRIVER.get().clone() 43 } 44 45 // lazy_static! { 46 // pub static ref PTM_DRIVER: Arc<TtyDriver> = { 47 // let mut ptm_driver = TtyDriver::new( 48 // NR_UNIX98_PTY_MAX, 49 // "ptm", 50 // 0, 51 // Major::UNIX98_PTY_MASTER_MAJOR, 52 // 0, 53 // TtyDriverType::Pty, 54 // *TTY_STD_TERMIOS, 55 // Arc::new(Unix98PtyDriverInner::new()), 56 // ); 57 58 // ptm_driver.set_subtype(TtyDriverSubType::PtyMaster); 59 // let term = ptm_driver.init_termios_mut(); 60 // term.input_mode = InputMode::empty(); 61 // term.output_mode = OutputMode::empty(); 62 // term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD; 63 // term.local_mode = LocalMode::empty(); 64 // term.input_speed = 38400; 65 // term.output_speed = 38400; 66 // TtyDriverManager::tty_register_driver(ptm_driver).unwrap() 67 // }; 68 // pub static ref PTS_DRIVER: Arc<TtyDriver> = { 69 // let mut pts_driver = TtyDriver::new( 70 // NR_UNIX98_PTY_MAX, 71 // "pts", 72 // 0, 73 // Major::UNIX98_PTY_SLAVE_MAJOR, 74 // 0, 75 // TtyDriverType::Pty, 76 // *TTY_STD_TERMIOS, 77 // Arc::new(Unix98PtyDriverInner::new()), 78 // ); 79 80 // pts_driver.set_subtype(TtyDriverSubType::PtySlave); 81 // let term = pts_driver.init_termios_mut(); 82 // term.input_mode = InputMode::empty(); 83 // term.output_mode = OutputMode::empty(); 84 // term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD; 85 // term.local_mode = LocalMode::empty(); 86 // term.input_speed = 38400; 87 // term.output_speed = 38400; 88 // TtyDriverManager::tty_register_driver(pts_driver).unwrap() 89 // }; 90 // } 91 92 pub struct PtyCommon; 93 94 impl PtyCommon { 95 pub fn pty_common_install( 96 driver: Arc<TtyDriver>, 97 tty: Arc<TtyCore>, 98 legacy: bool, 99 ) -> Result<(), SystemError> { 100 let core = tty.core(); 101 let other_driver = driver.other_pty_driver().unwrap(); 102 let other_tty = TtyCore::new(other_driver.clone(), core.index()); 103 other_driver.add_tty(other_tty.clone()); 104 105 let port0: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new()); 106 let port1: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new()); 107 108 let o_core = other_tty.core(); 109 110 if legacy { 111 core.init_termios(); 112 o_core.init_termios(); 113 114 driver 115 .other_pty_driver() 116 .unwrap() 117 .ttys() 118 .insert(core.index(), other_tty.clone()); 119 driver.ttys().insert(core.index(), tty.clone()); 120 } else { 121 *core.termios_write() = driver.init_termios(); 122 *o_core.termios_write() = driver.other_pty_driver().unwrap().init_termios(); 123 } 124 125 core.set_link(Arc::downgrade(&other_tty)); 126 o_core.set_link(Arc::downgrade(&tty)); 127 128 port0.setup_internal_tty(Arc::downgrade(&other_tty)); 129 port1.setup_internal_tty(Arc::downgrade(&tty)); 130 other_tty.set_port(port0); 131 tty.set_port(port1); 132 133 core.add_count(); 134 o_core.add_count(); 135 136 // 将pts加入pts Driver管理队列 137 PTS_DRIVER.ttys().insert(core.index(), other_tty); 138 139 Ok(()) 140 } 141 142 pub fn pty_common_open(core: &TtyCoreData) -> Result<(), SystemError> { 143 if let Some(link) = core.link() { 144 let link_core = link.core(); 145 146 if core.flags().contains(TtyFlag::OTHER_CLOSED) { 147 core.flags_write().insert(TtyFlag::IO_ERROR); 148 return Err(SystemError::EIO); 149 } 150 151 if link_core.flags().contains(TtyFlag::PTY_LOCK) { 152 core.flags_write().insert(TtyFlag::IO_ERROR); 153 return Err(SystemError::EIO); 154 } 155 156 if core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave 157 && link_core.count() != 1 158 { 159 // 只能有一个master,如果当前为slave,则link的count必须为1 160 core.flags_write().insert(TtyFlag::IO_ERROR); 161 return Err(SystemError::EIO); 162 } 163 164 core.flags_write().remove(TtyFlag::IO_ERROR); 165 link_core.flags_write().remove(TtyFlag::OTHER_CLOSED); 166 core.flags_write().insert(TtyFlag::THROTTLED); 167 168 return Ok(()); 169 } 170 return Err(SystemError::ENODEV); 171 } 172 173 pub fn pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> { 174 let user_reader = 175 UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 176 177 if *user_reader.read_one_from_user::<i32>(0)? != 0 { 178 tty.flags_write().insert(TtyFlag::PTY_LOCK); 179 } else { 180 tty.flags_write().remove(TtyFlag::PTY_LOCK); 181 } 182 183 Ok(()) 184 } 185 186 pub fn pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> { 187 let mut user_writer = 188 UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 189 user_writer.copy_one_to_user(&tty.flags().contains(TtyFlag::PTY_LOCK), 0)?; 190 Ok(()) 191 } 192 193 pub fn pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> { 194 let user_reader = 195 UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 196 197 let mut ctrl = tty.contorl_info_irqsave(); 198 if *user_reader.read_one_from_user::<i32>(0)? != 0 { 199 if !ctrl.packet { 200 tty.link().unwrap().core().contorl_info_irqsave().pktstatus = 201 TtyPacketStatus::empty(); 202 ctrl.packet = true; 203 } 204 } else { 205 ctrl.packet = false; 206 } 207 Ok(()) 208 } 209 210 pub fn pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> { 211 let mut user_writer = 212 UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 213 user_writer.copy_one_to_user(&tty.contorl_info_irqsave().packet, 0)?; 214 Ok(()) 215 } 216 217 pub fn unix98pty_init() -> Result<(), SystemError> { 218 let ptm_driver = ptm_driver(); 219 let pts_driver = pts_driver(); 220 ptm_driver.set_other_pty_driver(Arc::downgrade(&pts_driver)); 221 pts_driver.set_other_pty_driver(Arc::downgrade(&ptm_driver)); 222 223 let idt = IdTable::new( 224 String::from("ptmx"), 225 Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 2)), 226 ); 227 let ptmx_dev = TtyDevice::new( 228 "ptmx".to_string(), 229 idt.clone(), 230 TtyType::Pty(super::tty_device::PtyType::Ptm), 231 ); 232 233 ptmx_dev.inner_write().metadata_mut().raw_dev = idt.device_number(); 234 device_register(ptmx_dev.clone())?; 235 devfs_register("ptmx", ptmx_dev)?; 236 237 TTY_DRIVERS.lock().push(ptm_driver); 238 TTY_DRIVERS.lock().push(pts_driver); 239 240 Ok(()) 241 } 242 } 243 244 #[unified_init(INITCALL_DEVICE)] 245 #[inline(never)] 246 pub fn pty_init() -> Result<(), SystemError> { 247 let mut ptm_driver = TtyDriver::new( 248 NR_UNIX98_PTY_MAX, 249 "ptm", 250 0, 251 Major::UNIX98_PTY_MASTER_MAJOR, 252 0, 253 TtyDriverType::Pty, 254 *TTY_STD_TERMIOS, 255 Arc::new(Unix98PtyDriverInner::new()), 256 None, 257 ); 258 ptm_driver.set_subtype(TtyDriverSubType::PtyMaster); 259 let term = ptm_driver.init_termios_mut(); 260 term.input_mode = InputMode::empty(); 261 term.output_mode = OutputMode::empty(); 262 term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD; 263 term.local_mode = LocalMode::empty(); 264 term.input_speed = 38400; 265 term.output_speed = 38400; 266 PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap()); 267 268 let mut pts_driver = TtyDriver::new( 269 NR_UNIX98_PTY_MAX, 270 "pts", 271 0, 272 Major::UNIX98_PTY_SLAVE_MAJOR, 273 0, 274 TtyDriverType::Pty, 275 *TTY_STD_TERMIOS, 276 Arc::new(Unix98PtyDriverInner::new()), 277 None, 278 ); 279 pts_driver.set_subtype(TtyDriverSubType::PtySlave); 280 let term = pts_driver.init_termios_mut(); 281 term.input_mode = InputMode::empty(); 282 term.output_mode = OutputMode::empty(); 283 term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD; 284 term.local_mode = LocalMode::empty(); 285 term.input_speed = 38400; 286 term.output_speed = 38400; 287 PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap()); 288 289 return PtyCommon::unix98pty_init(); 290 } 291