Skip to content

Commit

Permalink
PS2: Increase timeout and add proper error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
fruhland committed Mar 11, 2024
1 parent e16e2ef commit 1621ad7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 52 deletions.
73 changes: 24 additions & 49 deletions os/kernel/src/device/ps2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use alloc::boxed::Box;
use log::info;
use nolock::queues::mpmc::bounded::scq::{Receiver, Sender};
use nolock::queues::{mpmc, DequeueError};
use ps2::error::{ControllerError, KeyboardError};
use ps2::flags::{ControllerConfigFlags, KeyboardLedFlags};
use ps2::{Controller, KeyboardType};
use spin::Mutex;
Expand Down Expand Up @@ -70,104 +69,80 @@ impl InterruptHandler for KeyboardInterruptHandler {
impl PS2 {
pub fn new() -> Self {
Self {
controller: unsafe { Mutex::new(Controller::new()) },
controller: unsafe { Mutex::new(Controller::with_timeout(1000000)) },
keyboard: Keyboard::new(KEYBOARD_BUFFER_CAPACITY),
}
}

pub fn init_controller(&self) -> Result<(), ControllerError> {
pub fn init_controller(&self) {
info!("Initializing controller");
let mut controller = self.controller.lock();

// Disable ports
controller.disable_keyboard()?;
controller.disable_mouse()?;
controller.disable_keyboard().expect("Failed to disable first port");
controller.disable_mouse().expect("Failed to disable second port");

// Flush output buffer
let _ = controller.read_data();

// Disable interrupts and translation
let mut config = controller.read_config()?;
config.set(
ControllerConfigFlags::ENABLE_KEYBOARD_INTERRUPT
| ControllerConfigFlags::ENABLE_MOUSE_INTERRUPT
| ControllerConfigFlags::ENABLE_TRANSLATE,
false,
);
controller.write_config(config)?;
let mut config = controller.read_config().expect("Failed to read config");
config.set(ControllerConfigFlags::ENABLE_KEYBOARD_INTERRUPT | ControllerConfigFlags::ENABLE_MOUSE_INTERRUPT | ControllerConfigFlags::ENABLE_TRANSLATE, false);
controller.write_config(config).expect("Failed to write config");

// Perform self test on controller
controller.test_controller()?;
controller.test_controller().expect("Self test failed");
info!("Self test result is OK");

// Check if the controller has reset itself during the self test and if so, write the configuration byte again
if controller.read_config()? != config {
controller.write_config(config)?;
if controller.read_config().expect("Failed to read config") != config {
controller.write_config(config).expect("Failed to write config");
}

// Check if keyboard is present
if controller.test_keyboard().is_ok() {
// Enable keyboard
info!("First port detected");
controller.enable_keyboard()?;
controller.enable_keyboard().expect("Failed to enable first port");
config.set(ControllerConfigFlags::DISABLE_KEYBOARD, false);
config.set(ControllerConfigFlags::ENABLE_KEYBOARD_INTERRUPT, true);
controller.write_config(config)?;
controller.write_config(config).expect("Failed to write config");
info!("First port enabled");
} else {
panic!("No keyboard detected!");
}

// Check if mouse is present
if controller.test_mouse().is_ok() {
// Enable mouse
info!("Second port detected");
controller.enable_keyboard()?;
config.set(ControllerConfigFlags::DISABLE_MOUSE, false);
config.set(ControllerConfigFlags::ENABLE_MOUSE_INTERRUPT, true);
controller.write_config(config)?;
info!("Second port enabled");
}

return Ok(());
}

pub fn init_keyboard(&mut self) -> Result<(), KeyboardError> {
pub fn init_keyboard(&mut self) {
info!("Initializing keyboard");
let mut controller = self.controller.lock();

// Perform self test on keyboard
if controller.keyboard().reset_and_self_test().is_err() {
panic!("Keyboard is not working!");
}
controller.keyboard().reset_and_self_test().expect("Keyboard self test failed");
info!("Keyboard has been reset and self test result is OK");

// Enable keyboard translation if needed
controller.keyboard().disable_scanning()?;
let kb_type = controller.keyboard().get_keyboard_type()?;
controller.keyboard().disable_scanning().expect("Failed to disable scanning");
let kb_type = controller.keyboard().get_keyboard_type().expect("Failed to query keyboard type");
info!("Detected keyboard type [{:?}]", kb_type);

match kb_type {
KeyboardType::ATWithTranslation
| KeyboardType::MF2WithTranslation
| KeyboardType::ThinkPadWithTranslation => {
KeyboardType::ATWithTranslation | KeyboardType::MF2WithTranslation | KeyboardType::ThinkPadWithTranslation => {
info!("Enabling keyboard translation");
let mut config = controller.read_config()?;
let mut config = controller.read_config().expect("Failed to read config");
config.set(ControllerConfigFlags::ENABLE_TRANSLATE, true);
controller.write_config(config)?;
controller.write_config(config).expect("Failed to write config");
}
_ => info!("Keyboard does not need translation"),
}

// Setup keyboard
info!("Enabling keyboard");
controller.keyboard().set_defaults()?;
controller.keyboard().set_scancode_set(1)?;
controller.keyboard().set_typematic_rate_and_delay(0)?;
controller.keyboard().set_leds(KeyboardLedFlags::empty())?;
controller.keyboard().enable_scanning()?;

return Ok(());
controller.keyboard().set_defaults().expect("Failed to set default keyboard configuration");
controller.keyboard().set_scancode_set(1).expect("Failed to set scancode set");
controller.keyboard().set_typematic_rate_and_delay(0).expect("Failed to set typematic rate");
controller.keyboard().set_leds(KeyboardLedFlags::empty()).expect("Failed to set LEDs");
controller.keyboard().enable_scanning().expect("Failed to enable scanning");
}

pub fn keyboard(&self) -> &Keyboard {
Expand Down
6 changes: 3 additions & 3 deletions os/kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ pub fn init_terminal(buffer: *mut u8, pitch: u32, width: u32, height: u32, bpp:
pub fn init_keyboard() {
PS2.call_once(|| {
let mut ps2 = PS2::new();
ps2.init_controller().unwrap_or_else(|err| panic!("Failed to initialize PS2 controller (Error: {:?})", err));
ps2.init_keyboard().unwrap_or_else(|err| panic!("Failed to initialize PS2 keyboard (Error: {:?})", err));
ps2.init_controller();
ps2.init_keyboard();

return ps2;
});
Expand Down Expand Up @@ -266,7 +266,7 @@ pub fn terminal() -> &'static dyn Terminal {
}

pub fn ps2_devices() -> &'static PS2 {
PS2.get().expect("Trying to access keyboard before initialization!")
PS2.get().expect("Trying to access PS/2 devices before initialization!")
}

pub fn pci_bus() -> &'static PciBus {
Expand Down

0 comments on commit 1621ad7

Please sign in to comment.