diff --git a/kernel/include/kernel/Errors.h b/kernel/include/kernel/Errors.h index ca93466238..ae94a198de 100644 --- a/kernel/include/kernel/Errors.h +++ b/kernel/include/kernel/Errors.h @@ -11,10 +11,6 @@ namespace Kernel ACPI_NoRootSDT, ACPI_NoSuchHeader, ACPI_RootInvalid, - PS2_Timeout, - PS2_SelfTest, - PS2_Reset, - PS2_UnsupportedDevice, Ext2_Invalid, Ext2_Corrupted, Ext2_NoInodes, diff --git a/kernel/include/kernel/Input/PS2/Config.h b/kernel/include/kernel/Input/PS2/Config.h index 6a23b101dd..44e3bc1419 100644 --- a/kernel/include/kernel/Input/PS2/Config.h +++ b/kernel/include/kernel/Input/PS2/Config.h @@ -14,8 +14,8 @@ namespace Kernel::Input::PS2 enum Status : uint8_t { - OUTPUT_FULL = (1 << 0), - INPUT_FULL = (1 << 1), + OUTPUT_STATUS = (1 << 0), + INPUT_STATUS = (1 << 1), SYSTEM = (1 << 2), DEVICE_OR_CONTROLLER = (1 << 3), TIMEOUT_ERROR = (1 << 6), diff --git a/kernel/include/kernel/Input/PS2/Controller.h b/kernel/include/kernel/Input/PS2/Controller.h index 1c48a7d0dc..f64513c06f 100644 --- a/kernel/include/kernel/Input/PS2/Controller.h +++ b/kernel/include/kernel/Input/PS2/Controller.h @@ -1,8 +1,10 @@ #pragma once -#include +#include #include +#include #include +#include namespace Kernel::Input { @@ -15,7 +17,10 @@ namespace Kernel::Input static BAN::ErrorOr initialize(); static PS2Controller& get(); - void send_byte(const PS2Device*, uint8_t); + BAN::ErrorOr device_send_byte(PS2Device* device, uint8_t byte); + + [[nodiscard]] bool lock_command(PS2Device*); + void unlock_command(PS2Device*); private: PS2Controller() = default; @@ -25,8 +30,21 @@ namespace Kernel::Input BAN::ErrorOr reset_device(uint8_t); BAN::ErrorOr set_scanning(uint8_t, bool); + BAN::ErrorOr read_byte(); + BAN::ErrorOr send_byte(uint16_t port, uint8_t byte); + + BAN::ErrorOr send_command(PS2::Command command); + BAN::ErrorOr send_command(PS2::Command command, uint8_t data); + + BAN::ErrorOr device_send_byte(uint8_t device_index, uint8_t byte); + BAN::ErrorOr device_read_ack(uint8_t device_index); + private: - PS2Device* m_devices[2] { nullptr, nullptr }; + BAN::RefPtr m_devices[2]; + RecursiveSpinLock m_lock; + + PS2Device* m_executing_device { nullptr }; + PS2Device* m_pending_device { nullptr }; }; } diff --git a/kernel/include/kernel/Input/PS2/Device.h b/kernel/include/kernel/Input/PS2/Device.h index 71051a6e8c..2c661a1c34 100644 --- a/kernel/include/kernel/Input/PS2/Device.h +++ b/kernel/include/kernel/Input/PS2/Device.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include namespace Kernel::Input { @@ -13,8 +15,8 @@ namespace Kernel::Input virtual void send_initialize() = 0; - bool append_command_queue(uint8_t command); - bool append_command_queue(uint8_t command, uint8_t data); + bool append_command_queue(uint8_t command, uint8_t response_size); + bool append_command_queue(uint8_t command, uint8_t data, uint8_t response_size); virtual void handle_irq() final override; virtual void handle_byte(uint8_t) = 0; @@ -24,13 +26,22 @@ namespace Kernel::Input virtual dev_t rdev() const final override { return m_rdev; } private: - void update(); + void update_command(); private: enum class State { Normal, WaitingAck, + WaitingResponse, + }; + + struct Command + { + uint8_t out_data[2]; + uint8_t out_count; + uint8_t in_count; + uint8_t send_index; }; private: @@ -39,7 +50,9 @@ namespace Kernel::Input PS2Controller& m_controller; State m_state = State::Normal; - BAN::CircularQueue m_command_queue; + BAN::CircularQueue m_command_queue; + + friend class PS2Controller; }; } diff --git a/kernel/kernel/Errors.cpp b/kernel/kernel/Errors.cpp index acc21ed3c0..62eb0569c6 100644 --- a/kernel/kernel/Errors.cpp +++ b/kernel/kernel/Errors.cpp @@ -8,10 +8,6 @@ namespace Kernel "ACPI could not find root SDT header"sv, "ACPI no such header"sv, "ACPI root invalid", - "PS/2 device timeout"sv, - "PS/2 controller self test failed"sv, - "PS/2 reset failed"sv, - "PS/2 unsupported device"sv, "Invalid ext2 filesystem"sv, "Ext2 filesystem corrupted"sv, "Ext2 filesystem out of inodes"sv, diff --git a/kernel/kernel/Input/PS2/Controller.cpp b/kernel/kernel/Input/PS2/Controller.cpp index 779227e587..b614e76b1b 100644 --- a/kernel/kernel/Input/PS2/Controller.cpp +++ b/kernel/kernel/Input/PS2/Controller.cpp @@ -10,64 +10,109 @@ #include #include +#define DEBUG_PS2 1 + namespace Kernel::Input { - static constexpr uint64_t s_device_timeout_ms = 100; + static constexpr uint64_t s_ps2_timeout_ms = 100; - static void controller_send_command(PS2::Command command) - { - IO::outb(PS2::IOPort::COMMAND, command); - } + static PS2Controller* s_instance = nullptr; - static void controller_send_command(PS2::Command command, uint8_t data) + BAN::ErrorOr PS2Controller::send_byte(uint16_t port, uint8_t byte) { - IO::outb(PS2::IOPort::COMMAND, command); - while (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL) - continue; - IO::outb(PS2::IOPort::DATA, data); - } - - static uint8_t wait_and_read() - { - while (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL)) - continue; - return IO::inb(PS2::IOPort::DATA); - } - - static BAN::ErrorOr device_send_byte(uint8_t device, uint8_t byte) - { - if (device == 1) - IO::outb(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT); - uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms; + LockGuard _(m_lock); + uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms; while (SystemTimer::get().ms_since_boot() < timeout) { - if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL)) - { - IO::outb(PS2::IOPort::DATA, byte); - return {}; - } + if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_STATUS) + continue; + IO::outb(port, byte); + return {}; } - return BAN::Error::from_error_code(ErrorCode::PS2_Timeout); + return BAN::Error::from_errno(ETIMEDOUT); } - static BAN::ErrorOr device_read_byte() + BAN::ErrorOr PS2Controller::read_byte() { - uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms; + LockGuard _(m_lock); + uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms; while (SystemTimer::get().ms_since_boot() < timeout) - if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL) - return IO::inb(PS2::IOPort::DATA); - return BAN::Error::from_error_code(ErrorCode::PS2_Timeout); + { + if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_STATUS)) + continue; + return IO::inb(PS2::IOPort::DATA); + } + return BAN::Error::from_errno(ETIMEDOUT); } - static BAN::ErrorOr device_wait_ack() + BAN::ErrorOr PS2Controller::send_command(PS2::Command command) { - while (TRY(device_read_byte()) != PS2::Response::ACK) - continue;; + LockGuard _(m_lock); + TRY(send_byte(PS2::IOPort::COMMAND, command)); return {}; } - static PS2Controller* s_instance = nullptr; + BAN::ErrorOr PS2Controller::send_command(PS2::Command command, uint8_t data) + { + LockGuard _(m_lock); + TRY(send_byte(PS2::IOPort::COMMAND, command)); + TRY(send_byte(PS2::IOPort::DATA, data)); + return {}; + } + + bool PS2Controller::lock_command(PS2Device* device) + { + if (m_executing_device && m_executing_device != device) + { + ASSERT(!m_pending_device || m_pending_device == device); + m_pending_device = device; + return false; + } + + m_executing_device = device; + return true; + } + + void PS2Controller::unlock_command(PS2Device* device) + { + ASSERT(m_executing_device == device); + m_executing_device = nullptr; + if (m_pending_device) + { + m_executing_device = m_pending_device; + m_pending_device = nullptr; + m_executing_device->update_command(); + } + } + + BAN::ErrorOr PS2Controller::device_send_byte(uint8_t device_index, uint8_t byte) + { + LockGuard _(m_lock); + if (device_index == 1) + TRY(send_byte(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT)); + TRY(send_byte(PS2::IOPort::DATA, byte)); + return {}; + } + + BAN::ErrorOr PS2Controller::device_send_byte(PS2Device* device, uint8_t byte) + { + ASSERT(device); + ASSERT(device == m_devices[0].ptr() || device == m_devices[1].ptr()); + TRY(device_send_byte(device == m_devices[0].ptr() ? 0 : 1, byte)); + return {}; + } + + BAN::ErrorOr PS2Controller::device_read_ack(uint8_t device_index) + { + LockGuard _(m_lock); + if (TRY(read_byte()) != PS2::Response::ACK) + { + dwarnln_if(DEBUG_PS2, "PS/2 device on port {} did not respond with expected ACK", device_index); + return BAN::Error::from_errno(EBADMSG); + } + return {}; + } BAN::ErrorOr PS2Controller::initialize() { @@ -96,47 +141,59 @@ namespace Kernel::Input // FIXME // Step 3: Disable Devices - controller_send_command(PS2::Command::DISABLE_FIRST_PORT); - controller_send_command(PS2::Command::DISABLE_SECOND_PORT); + TRY(send_command(PS2::Command::DISABLE_FIRST_PORT)); + TRY(send_command(PS2::Command::DISABLE_SECOND_PORT)); // Step 4: Flush The Output Buffer - IO::inb(PS2::IOPort::DATA); + while (!read_byte().is_error()) + continue; // Step 5: Set the Controller Configuration Byte - controller_send_command(PS2::Command::READ_CONFIG); - uint8_t config = wait_and_read(); + TRY(send_command(PS2::Command::READ_CONFIG)); + uint8_t config = TRY(read_byte()); config &= ~PS2::Config::INTERRUPT_FIRST_PORT; config &= ~PS2::Config::INTERRUPT_SECOND_PORT; config &= ~PS2::Config::TRANSLATION_FIRST_PORT; - controller_send_command(PS2::Command::WRITE_CONFIG, config); + TRY(send_command(PS2::Command::WRITE_CONFIG, config)); // Step 6: Perform Controller Self Test - controller_send_command(PS2::Command::TEST_CONTROLLER); - if (wait_and_read() != PS2::Response::TEST_CONTROLLER_PASS) - return BAN::Error::from_error_code(ErrorCode::PS2_SelfTest); + TRY(send_command(PS2::Command::TEST_CONTROLLER)); + if (TRY(read_byte()) != PS2::Response::TEST_CONTROLLER_PASS) + { + dwarnln_if(DEBUG_PS2, "PS/2 Controller test failed"); + return BAN::Error::from_errno(ENODEV); + } // NOTE: self test might reset the device so we set the config byte again - controller_send_command(PS2::Command::WRITE_CONFIG, config); + TRY(send_command(PS2::Command::WRITE_CONFIG, config)); // Step 7: Determine If There Are 2 Channels bool valid_ports[2] { true, false }; if (config & PS2::Config::CLOCK_SECOND_PORT) { - controller_send_command(PS2::Command::ENABLE_SECOND_PORT); - controller_send_command(PS2::Command::READ_CONFIG); - if (!(wait_and_read() & PS2::Config::CLOCK_SECOND_PORT)) + TRY(send_command(PS2::Command::ENABLE_SECOND_PORT)); + TRY(send_command(PS2::Command::READ_CONFIG)); + if (!(TRY(read_byte()) & PS2::Config::CLOCK_SECOND_PORT)) + { valid_ports[1] = true; - controller_send_command(PS2::Command::DISABLE_SECOND_PORT); + TRY(send_command(PS2::Command::DISABLE_SECOND_PORT)); + } } // Step 8: Perform Interface Tests - controller_send_command(PS2::Command::TEST_FIRST_PORT); - if (wait_and_read() != PS2::Response::TEST_FIRST_PORT_PASS) + TRY(send_command(PS2::Command::TEST_FIRST_PORT)); + if (TRY(read_byte()) != PS2::Response::TEST_FIRST_PORT_PASS) + { + dwarnln_if(DEBUG_PS2, "PS/2 first port test failed"); valid_ports[0] = false; + } if (valid_ports[1]) { - controller_send_command(PS2::Command::TEST_SECOND_PORT); - if (wait_and_read() != PS2::Response::TEST_SECOND_PORT_PASS) + TRY(send_command(PS2::Command::TEST_SECOND_PORT)); + if (TRY(read_byte()) != PS2::Response::TEST_SECOND_PORT_PASS) + { + dwarnln_if(DEBUG_PS2, "PS/2 second port test failed"); valid_ports[1] = false; + } } if (!valid_ports[0] && !valid_ports[1]) return {}; @@ -146,9 +203,13 @@ namespace Kernel::Input { if (!valid_ports[device]) continue; - controller_send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT); + TRY(send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT)); if (set_scanning(device, false).is_error()) + { + dwarnln_if(DEBUG_PS2, "PS/2 could not disable device scanning"); valid_ports[device] = false; + } + TRY(send_command(device == 0 ? PS2::Command::DISABLE_FIRST_PORT : PS2::Command::DISABLE_SECOND_PORT)); } // Step 10: Reset Devices @@ -156,10 +217,18 @@ namespace Kernel::Input { if (!valid_ports[device]) continue; - if (reset_device(device).is_error()) + if (auto ret = reset_device(device); ret.is_error()) + { + dwarnln_if(DEBUG_PS2, "PS/2 device reset failed: {}", ret.error()); valid_ports[device] = false; - if (set_scanning(device, false).is_error()) + continue; + } + if (auto ret = set_scanning(device, false); ret.is_error()) + { + dwarnln_if(DEBUG_PS2, "PS/2 device scan disabling failed: {}", ret.error()); valid_ports[device] = false; + continue; + } } // Step 11: Initialize Device Drivers @@ -168,7 +237,7 @@ namespace Kernel::Input if (!valid_ports[device]) continue; if (auto res = initialize_device(device); res.is_error()) - dprintln("{}", res.error()); + dwarnln_if(DEBUG_PS2, "PS/2 device initialization failed: {}", res.error()); } if (m_devices[0]) @@ -184,11 +253,11 @@ namespace Kernel::Input config |= PS2::Config::INTERRUPT_SECOND_PORT; } - controller_send_command(PS2::Command::WRITE_CONFIG, config); + TRY(send_command(PS2::Command::WRITE_CONFIG, config)); for (uint8_t device = 0; device < 2; device++) { - if (m_devices[device] == nullptr) + if (!m_devices[device]) continue; m_devices[device]->send_initialize(); DevFileSystem::get().add_device(m_devices[device]); @@ -200,13 +269,13 @@ namespace Kernel::Input BAN::ErrorOr PS2Controller::initialize_device(uint8_t device) { TRY(device_send_byte(device, PS2::DeviceCommand::IDENTIFY)); - TRY(device_wait_ack()); + TRY(device_read_ack(device)); uint8_t bytes[2] {}; uint8_t index = 0; for (uint8_t i = 0; i < 2; i++) { - auto res = device_read_byte(); + auto res = read_byte(); if (res.is_error()) break; bytes[index++] = res.value(); @@ -214,37 +283,43 @@ namespace Kernel::Input // Standard PS/2 Mouse if (index == 1 && (bytes[0] == 0x00)) + { + dprintln_if(DEBUG_PS2, "PS/2 found mouse"); m_devices[device] = TRY(PS2Mouse::create(*this)); + } // MF2 Keyboard else if (index == 2 && (bytes[0] == 0xAB && bytes[1] == 0x83)) + { + dprintln_if(DEBUG_PS2, "PS/2 found keyboard"); m_devices[device] = TRY(PS2Keyboard::create(*this)); + } if (m_devices[device]) return {}; - return BAN::Error::from_error_code(ErrorCode::PS2_UnsupportedDevice); - } - - void PS2Controller::send_byte(const PS2Device* device, uint8_t byte) - { - ASSERT(device != nullptr && (device == m_devices[0] || device == m_devices[1])); - uint8_t device_index = (device == m_devices[0]) ? 0 : 1; - MUST(device_send_byte(device_index, byte)); + dprintln_if(DEBUG_PS2, "PS/2 unsupported device {2H} {2H} ({} bytes) on port {}", bytes[0], bytes[1], index, device); + return BAN::Error::from_errno(ENOTSUP); } BAN::ErrorOr PS2Controller::reset_device(uint8_t device) { TRY(device_send_byte(device, PS2::DeviceCommand::RESET)); - TRY(device_wait_ack()); - if (TRY(device_read_byte()) != PS2::Response::SELF_TEST_PASS) - return BAN::Error::from_error_code(ErrorCode::PS2_Reset); + TRY(device_read_ack(device)); + if (TRY(read_byte()) != PS2::Response::SELF_TEST_PASS) + { + dwarnln_if(DEBUG_PS2, "PS/2 device self test failed"); + return BAN::Error::from_errno(ENODEV); + } + // device might send extra data + while (!read_byte().is_error()) + continue; return {}; } BAN::ErrorOr PS2Controller::set_scanning(uint8_t device, bool enabled) { TRY(device_send_byte(device, enabled ? PS2::DeviceCommand::ENABLE_SCANNING : PS2::DeviceCommand::DISABLE_SCANNING)); - TRY(device_wait_ack()); + TRY(device_read_ack(device)); return {}; } diff --git a/kernel/kernel/Input/PS2/Device.cpp b/kernel/kernel/Input/PS2/Device.cpp index 5682ba28c9..1f51e5614e 100644 --- a/kernel/kernel/Input/PS2/Device.cpp +++ b/kernel/kernel/Input/PS2/Device.cpp @@ -15,28 +15,39 @@ namespace Kernel::Input , m_controller(controller) { } - bool PS2Device::append_command_queue(uint8_t command) + bool PS2Device::append_command_queue(uint8_t command, uint8_t response_size) { + CriticalScope _; if (m_command_queue.size() + 1 >= m_command_queue.capacity()) { dprintln("PS/2 command queue full"); return false; } - m_command_queue.push(command); - update(); + m_command_queue.push(Command { + .out_data = { command, 0x00 }, + .out_count = 1, + .in_count = response_size, + .send_index = 0 + }); + update_command(); return true; } - bool PS2Device::append_command_queue(uint8_t command, uint8_t data) + bool PS2Device::append_command_queue(uint8_t command, uint8_t data, uint8_t response_size) { - if (m_command_queue.size() + 2 >= m_command_queue.capacity()) + CriticalScope _; + if (m_command_queue.size() + 1 >= m_command_queue.capacity()) { dprintln("PS/2 command queue full"); return false; } - m_command_queue.push(command); - m_command_queue.push(data); - update(); + m_command_queue.push(Command { + .out_data = { command, data }, + .out_count = 2, + .in_count = response_size, + .send_index = 0 + }); + update_command(); return true; } @@ -44,8 +55,6 @@ namespace Kernel::Input { uint8_t byte = IO::inb(PS2::IOPort::DATA); - // NOTE: This implementation does not allow using commands - // that respond with more bytes than ACK switch (m_state) { case State::WaitingAck: @@ -53,9 +62,20 @@ namespace Kernel::Input switch (byte) { case PS2::Response::ACK: - m_command_queue.pop(); - m_state = State::Normal; + { + auto& command = m_command_queue.front(); + if (++command.send_index < command.out_count) + m_state = State::Normal; + else if (command.in_count > 0) + m_state = State::WaitingResponse; + else + { + m_command_queue.pop(); + m_state = State::Normal; + m_controller.unlock_command(this); + } break; + } case PS2::Response::RESEND: m_state = State::Normal; break; @@ -65,6 +85,17 @@ namespace Kernel::Input } break; } + case State::WaitingResponse: + { + if (--m_command_queue.front().in_count <= 0) + { + m_command_queue.pop(); + m_state = State::Normal; + m_controller.unlock_command(this); + } + handle_byte(byte); + break; + } case State::Normal: { handle_byte(byte); @@ -72,17 +103,28 @@ namespace Kernel::Input } } - update(); + update_command(); } - void PS2Device::update() + void PS2Device::update_command() { - if (m_state == State::WaitingAck) + ASSERT(!interrupts_enabled()); + + if (m_state != State::Normal) return; if (m_command_queue.empty()) return; + + const auto& command = m_command_queue.front(); + ASSERT(command.send_index < command.out_count); + + if (!m_controller.lock_command(this)) + return; + m_state = State::WaitingAck; - m_controller.send_byte(this, m_command_queue.front()); + auto ret = m_controller.device_send_byte(this, command.out_data[command.send_index]); + if (ret.is_error()) + dwarnln("Could not send byte to device: {}", ret.error()); } } diff --git a/kernel/kernel/Input/PS2/Keyboard.cpp b/kernel/kernel/Input/PS2/Keyboard.cpp index 6aa1efedf0..23251afa05 100644 --- a/kernel/kernel/Input/PS2/Keyboard.cpp +++ b/kernel/kernel/Input/PS2/Keyboard.cpp @@ -25,9 +25,9 @@ namespace Kernel::Input void PS2Keyboard::send_initialize() { - append_command_queue(Command::SET_LEDS, 0x00); - append_command_queue(Command::SCANCODE, PS2::KBScancode::SET_SCANCODE_SET2); - append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING); + append_command_queue(Command::SET_LEDS, 0x00, 0); + append_command_queue(Command::SCANCODE, PS2::KBScancode::SET_SCANCODE_SET2, 0); + append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); } void PS2Keyboard::handle_device_command_response(uint8_t byte) @@ -148,7 +148,7 @@ namespace Kernel::Input new_leds |= PS2::KBLeds::NUM_LOCK; if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::CapsLock) new_leds |= PS2::KBLeds::CAPS_LOCK; - append_command_queue(Command::SET_LEDS, new_leds); + append_command_queue(Command::SET_LEDS, new_leds, 0); } BAN::ErrorOr PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer) diff --git a/kernel/kernel/Input/PS2/Mouse.cpp b/kernel/kernel/Input/PS2/Mouse.cpp index 103d620c17..42bc11a988 100644 --- a/kernel/kernel/Input/PS2/Mouse.cpp +++ b/kernel/kernel/Input/PS2/Mouse.cpp @@ -26,10 +26,10 @@ namespace Kernel::Input void PS2Mouse::send_initialize() { // Query extensions - append_command_queue(Command::SET_SAMPLE_RATE, 200); - append_command_queue(Command::SET_SAMPLE_RATE, 100); - append_command_queue(Command::SET_SAMPLE_RATE, 80); - append_command_queue(PS2::DeviceCommand::IDENTIFY); + append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); + append_command_queue(Command::SET_SAMPLE_RATE, 100, 0); + append_command_queue(Command::SET_SAMPLE_RATE, 80, 0); + append_command_queue(PS2::DeviceCommand::IDENTIFY, 1); } void PS2Mouse::initialize_extensions(uint8_t byte) @@ -48,10 +48,10 @@ namespace Kernel::Input else { m_mouse_id = 0x03; - append_command_queue(Command::SET_SAMPLE_RATE, 200); - append_command_queue(Command::SET_SAMPLE_RATE, 200); - append_command_queue(Command::SET_SAMPLE_RATE, 80); - append_command_queue(PS2::DeviceCommand::IDENTIFY); + append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); + append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); + append_command_queue(Command::SET_SAMPLE_RATE, 80, 0); + append_command_queue(PS2::DeviceCommand::IDENTIFY, 1); } break; case 0x04: @@ -65,8 +65,8 @@ namespace Kernel::Input if (m_enabled) { - append_command_queue(Command::SET_SAMPLE_RATE, 100); - append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING); + append_command_queue(Command::SET_SAMPLE_RATE, 100, 0); + append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); } }