mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 13:30:31 +00:00
Kernel: Drain I8042 PS/2 keyboard output after enabling
As soon as we enable the first PS/2 port on the I8042 controller, the output buffer may become full. We need to drain it before attempting any new commands with the controller (such as enabling the second PS/2 port). Fixes #10872.
This commit is contained in:
parent
5e3fe52fc4
commit
86a1ff5204
Notes:
sideshowbarker
2024-07-18 01:15:53 +09:00
Author: https://github.com/gmta Commit: https://github.com/SerenityOS/serenity/commit/86a1ff52040 Pull-request: https://github.com/SerenityOS/serenity/pull/10874 Issue: https://github.com/SerenityOS/serenity/issues/10872
2 changed files with 7 additions and 6 deletions
|
@ -36,13 +36,12 @@ UNMAP_AFTER_INIT void I8042Controller::detect_devices()
|
|||
u8 configuration;
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
// Disable devices
|
||||
|
||||
drain_output_buffer();
|
||||
|
||||
do_wait_then_write(I8042Port::Command, I8042Command::DisableFirstPS2Port);
|
||||
do_wait_then_write(I8042Port::Command, I8042Command::DisableSecondPS2Port); // ignored if it doesn't exist
|
||||
|
||||
// Drain buffers
|
||||
do_drain();
|
||||
|
||||
do_wait_then_write(I8042Port::Command, I8042Command::ReadConfiguration);
|
||||
configuration = do_wait_then_read(I8042Port::Buffer);
|
||||
do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration);
|
||||
|
@ -75,6 +74,8 @@ UNMAP_AFTER_INIT void I8042Controller::detect_devices()
|
|||
dbgln("I8042: Keyboard port not available");
|
||||
}
|
||||
|
||||
drain_output_buffer();
|
||||
|
||||
if (m_is_dual_channel) {
|
||||
do_wait_then_write(I8042Port::Command, I8042Command::TestSecondPS2Port);
|
||||
m_second_port_available = (do_wait_then_read(I8042Port::Buffer) == 0);
|
||||
|
@ -152,7 +153,7 @@ bool I8042Controller::irq_process_input_buffer(HIDDevice::Type instrument_type)
|
|||
return false;
|
||||
}
|
||||
|
||||
void I8042Controller::do_drain()
|
||||
void I8042Controller::drain_output_buffer()
|
||||
{
|
||||
for (;;) {
|
||||
u8 status = IO::in8(I8042Port::Status);
|
||||
|
|
|
@ -135,7 +135,6 @@ public:
|
|||
|
||||
private:
|
||||
I8042Controller();
|
||||
void do_drain();
|
||||
bool do_reset_device(HIDDevice::Type);
|
||||
u8 do_send_command(HIDDevice::Type type, u8 data);
|
||||
u8 do_send_command(HIDDevice::Type device, u8 command, u8 data);
|
||||
|
@ -143,6 +142,7 @@ private:
|
|||
u8 do_read_from_device(HIDDevice::Type device);
|
||||
void do_wait_then_write(u8 port, u8 data);
|
||||
u8 do_wait_then_read(u8 port);
|
||||
void drain_output_buffer();
|
||||
|
||||
Spinlock m_lock;
|
||||
bool m_first_port_available { false };
|
||||
|
|
Loading…
Reference in a new issue