proka_kernel/drivers/char/
serial.rs1extern crate alloc;
2
3use super::super::{CharDevice, Device, DeviceError, DeviceInner, DeviceType, SharedDeviceOps};
4use alloc::format;
5use alloc::string::{String, ToString};
6use alloc::sync::Arc;
7use spin::RwLock;
8use uart_16550::SerialPort;
9
10pub struct SerialDevice {
11 port_address: u16,
12 name: String,
13 serial_port: RwLock<SerialPort>,
14}
15
16impl SerialDevice {
17 pub fn new(port_address: u16) -> Self {
18 let mut serial_port = unsafe { SerialPort::new(port_address) };
19 serial_port.init();
20 Self {
21 port_address,
22 name: format!("serial-{}", port_address),
23 serial_port: RwLock::new(serial_port),
24 }
25 }
26
27 pub fn create_device(major: u16, minor: u16, port_address: u16) -> Device {
30 let serial = Arc::new(SerialDevice::new(port_address));
31 Device::new(
32 serial.name().to_string(),
33 major,
34 minor,
35 DeviceInner::Char(serial),
36 )
37 }
38
39 pub fn create_device_auto_assign(port_address: u16) -> Device {
41 let serial = Arc::new(SerialDevice::new(port_address));
42 Device::new_auto_assign(serial.name().to_string(), DeviceInner::Char(serial))
43 }
44}
45
46impl SharedDeviceOps for SerialDevice {
47 fn name(&self) -> &str {
48 &self.name
49 }
50
51 fn device_type(&self) -> DeviceType {
52 DeviceType::Char
53 }
54
55 fn open(&self) -> Result<(), DeviceError> {
56 Ok(())
57 }
58
59 fn close(&self) -> Result<(), DeviceError> {
60 Ok(())
61 }
62
63 fn ioctl(&self, cmd: u64, _arg: u64) -> Result<u64, DeviceError> {
64 match cmd {
65 1 => Ok(self.port_address as u64),
66 _ => Err(DeviceError::NotSupported),
67 }
68 }
69}
70
71impl CharDevice for SerialDevice {
72 fn read(&self, _buf: &mut [u8]) -> Result<usize, DeviceError> {
73 Err(DeviceError::NotSupported)
74 }
75
76 fn write(&self, buf: &[u8]) -> Result<usize, DeviceError> {
77 let mut serial_port = self.serial_port.write();
78 for byte in buf {
79 serial_port.send(*byte);
80 }
81 Ok(buf.len())
82 }
83}