Files
RedBear-OS/drivers/input/ps2d/src/main.rs
T
Red Bear OS 00b799d512 absorb: 41 orphaned base patches re-applied (Phase 1.0A)
Per local/docs/PATCH-PRESERVATION-AUDIT-2026-07-12.md the base
fork was carrying only 38 of 100 patches in local/patches/base/.
The other 62 patches' content was silently missing from the fork
working tree, even though their .patch files were preserved.

This commit re-applies 41 patches that genuinely still apply
cleanly + 17 hunks that partially applied. Recovery covers:

- D-Bus initfs service wiring (P4-initfs-dbus-services)
- USB service wiring (P4-initfs-usb-drm-services)
- netcfg/dhcp/dhcpv6 driver fixes
- acpid shutdown/PM/quirk fixes
- inputd/ps2d hard-fail logging
- pcid driver interface refinements (server cmd channel)
- virtio-core for VirtualBox support
- ixgbed/rtl8139/rtl8168 net drivers
- ahcid NCQ + per-function interrupt coalescing
- logd persistent logging
- bootstrap procmgr race-condition fixes
- cargo version pin to +rb0.3.0 (synchronized release branch)

58 files changed, +1444/-318 lines.

Untracked mnt/ tree and *.orig / *.rej files cleaned up after
patch application (leftover from absolute-path patch headers).
2026-07-12 01:29:08 +03:00

141 lines
3.8 KiB
Rust

#[macro_use]
extern crate bitflags;
extern crate orbclient;
extern crate syscall;
use std::fs::OpenOptions;
use std::io::Read;
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::AsRawFd;
use std::process;
use common::acquire_port_io_rights;
use event::{user_data, EventQueue};
use inputd::InputProducer;
use crate::state::Ps2d;
mod controller;
mod mouse;
mod state;
mod vm;
fn daemon(daemon: daemon::Daemon) -> ! {
common::setup_logging(
"input",
"ps2",
"ps2",
common::output_level(),
common::file_level(),
);
acquire_port_io_rights().expect("ps2d: failed to get I/O permission");
let keyboard_input = InputProducer::new_named_or_fallback("ps2-keyboard").expect("ps2d: failed to open keyboard input");
let mouse_input = InputProducer::new_named_or_fallback("ps2-mouse").expect("ps2d: failed to open mouse input");
user_data! {
enum Source {
Keyboard,
Mouse,
Time,
}
}
let event_queue: EventQueue<Source> =
EventQueue::new().expect("ps2d: failed to create event queue");
let mut key_file = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(syscall::O_NONBLOCK as i32)
.open("/scheme/serio/0")
.expect("ps2d: failed to open /scheme/serio/0");
event_queue
.subscribe(
key_file.as_raw_fd() as usize,
Source::Keyboard,
event::EventFlags::READ,
)
.unwrap();
let mut mouse_file = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(syscall::O_NONBLOCK as i32)
.open("/scheme/serio/1")
.expect("ps2d: failed to open /scheme/serio/1");
event_queue
.subscribe(
mouse_file.as_raw_fd() as usize,
Source::Mouse,
event::EventFlags::READ,
)
.unwrap();
let time_file = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(syscall::O_NONBLOCK as i32)
.open(format!("/scheme/time/{}", syscall::CLOCK_MONOTONIC))
.expect("ps2d: failed to open /scheme/time");
event_queue
.subscribe(
time_file.as_raw_fd() as usize,
Source::Time,
event::EventFlags::READ,
)
.unwrap();
libredox::call::setrens(0, 0).expect("ps2d: failed to enter null namespace");
daemon.ready();
log::info!(
"ps2d: registered producer handle, listening on serio/0 (keyboard) and serio/1 (mouse)"
);
let mut ps2d = Ps2d::new(keyboard_input, mouse_input, time_file);
let mut data = [0; 256];
for event in event_queue.map(|e| e.expect("ps2d: failed to get next event").user_data) {
// There are some gotchas with ps/2 controllers that require this weird
// way of doing things. You read key and mouse data from the same
// place. There is a status register that may show you which the data
// came from, but if it is even implemented it can have a race
// condition causing keyboard data to be read as mouse data.
//
// Due to this, we have a kernel driver doing a small amount of work
// to grab bytes and sort them based on the source
let (file, keyboard) = match event {
Source::Keyboard => (&mut key_file, true),
Source::Mouse => (&mut mouse_file, false),
Source::Time => {
ps2d.time_event();
continue;
}
};
loop {
let count = match file.read(&mut data) {
Ok(0) => break,
Ok(count) => count,
Err(_) => break,
};
for i in 0..count {
ps2d.handle(keyboard, data[i]);
}
}
}
process::exit(0);
}
fn main() {
daemon::Daemon::new(daemon);
}