xref: /DragonOS/kernel/src/driver/tty/pty/mod.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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     );
257     ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
258     let term = ptm_driver.init_termios_mut();
259     term.input_mode = InputMode::empty();
260     term.output_mode = OutputMode::empty();
261     term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
262     term.local_mode = LocalMode::empty();
263     term.input_speed = 38400;
264     term.output_speed = 38400;
265     PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap());
266 
267     let mut pts_driver = TtyDriver::new(
268         NR_UNIX98_PTY_MAX,
269         "pts",
270         0,
271         Major::UNIX98_PTY_SLAVE_MAJOR,
272         0,
273         TtyDriverType::Pty,
274         *TTY_STD_TERMIOS,
275         Arc::new(Unix98PtyDriverInner::new()),
276     );
277     pts_driver.set_subtype(TtyDriverSubType::PtySlave);
278     let term = pts_driver.init_termios_mut();
279     term.input_mode = InputMode::empty();
280     term.output_mode = OutputMode::empty();
281     term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
282     term.local_mode = LocalMode::empty();
283     term.input_speed = 38400;
284     term.output_speed = 38400;
285     PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap());
286 
287     return PtyCommon::unix98pty_init();
288 }
289