Kernel: Fix PS/2 Controller if port 0 is empty

This commit is contained in:
Bananymous 2024-01-13 17:05:29 +02:00
parent 7e36a0be75
commit 56a29dc176
2 changed files with 15 additions and 6 deletions

View File

@ -38,6 +38,8 @@ namespace Kernel::Input
BAN::ErrorOr<void> device_send_byte(uint8_t device_index, uint8_t byte); BAN::ErrorOr<void> device_send_byte(uint8_t device_index, uint8_t byte);
BAN::ErrorOr<void> device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte); BAN::ErrorOr<void> device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte);
uint8_t get_device_index(PS2Device*) const;
private: private:
struct Command struct Command
{ {

View File

@ -89,11 +89,20 @@ namespace Kernel::Input
return {}; return {};
} }
uint8_t PS2Controller::get_device_index(PS2Device* device) const
{
ASSERT(device);
if (m_devices[0] && device == m_devices[0].ptr())
return 0;
if (m_devices[1] && device == m_devices[1].ptr())
return 1;
ASSERT_NOT_REACHED();
}
bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t response_size) bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t response_size)
{ {
// NOTE: command queue push/pop must be done without interrupts // NOTE: command queue push/pop must be done without interrupts
CriticalScope _; CriticalScope _;
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
if (m_command_queue.size() + 1 >= m_command_queue.capacity()) if (m_command_queue.size() + 1 >= m_command_queue.capacity())
{ {
dprintln("PS/2 command queue full"); dprintln("PS/2 command queue full");
@ -101,7 +110,7 @@ namespace Kernel::Input
} }
m_command_queue.push(Command { m_command_queue.push(Command {
.state = Command::State::NotSent, .state = Command::State::NotSent,
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1), .device_index = get_device_index(device),
.out_data = { command, 0x00 }, .out_data = { command, 0x00 },
.out_count = 1, .out_count = 1,
.in_count = response_size, .in_count = response_size,
@ -114,7 +123,6 @@ namespace Kernel::Input
{ {
// NOTE: command queue push/pop must be done without interrupts // NOTE: command queue push/pop must be done without interrupts
CriticalScope _; CriticalScope _;
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
if (m_command_queue.size() + 1 >= m_command_queue.capacity()) if (m_command_queue.size() + 1 >= m_command_queue.capacity())
{ {
dprintln("PS/2 command queue full"); dprintln("PS/2 command queue full");
@ -122,7 +130,7 @@ namespace Kernel::Input
} }
m_command_queue.push(Command { m_command_queue.push(Command {
.state = Command::State::NotSent, .state = Command::State::NotSent,
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1), .device_index = get_device_index(device),
.out_data = { command, data }, .out_data = { command, data },
.out_count = 2, .out_count = 2,
.in_count = response_size, .in_count = response_size,
@ -167,8 +175,7 @@ namespace Kernel::Input
return false; return false;
auto& command = m_command_queue.front(); auto& command = m_command_queue.front();
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr())); if (command.device_index != get_device_index(device))
if (command.device_index != (device == m_devices[0].ptr()) ? 0 : 1)
return false; return false;
switch (command.state) switch (command.state)