From 0f7cc468b2221d54ea79523922a2f21790c02645 Mon Sep 17 00:00:00 2001 From: Liav A Date: Thu, 22 Dec 2022 03:46:22 +0200 Subject: Kernel: Make i8042 controller initialization sequence more robust The setting of scan code set sequence is removed, as it's buggy and could lead the controller to fail immediately when doing self-test afterwards. We will restore it when we understand how to do so safely. Allow the user to determine a preferred detection path with a new kernel command line argument. The defualt option is to check i8042 presence with an ACPI check and if necessary - an "aggressive" test to determine i8042 existence in the system. Also, keep the i8042 controller pointer on the stack, so don't assign m_i8042_controller member pointer if it does not exist. --- Kernel/Devices/HID/HIDManagement.cpp | 37 +++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'Kernel/Devices') diff --git a/Kernel/Devices/HID/HIDManagement.cpp b/Kernel/Devices/HID/HIDManagement.cpp index 56b8d57e47..1ec30195c2 100644 --- a/Kernel/Devices/HID/HIDManagement.cpp +++ b/Kernel/Devices/HID/HIDManagement.cpp @@ -120,24 +120,39 @@ UNMAP_AFTER_INIT ErrorOr HIDManagement::enumerate() // emulation of the PS/2 controller if it was set by the BIOS. // If ACPI indicates we have an i8042 controller and the USB controller was // set to emulate PS/2, we should not initialize the PS/2 controller. - if (kernel_command_line().disable_ps2_controller()) - return {}; #if ARCH(X86_64) - m_i8042_controller = I8042Controller::initialize(); - - // Note: If ACPI is disabled or doesn't indicate that we have an i8042, we - // still perform a manual existence check via probing, which is relevant on - // QEMU, for example. This probing check is known to not work on bare metal - // in all cases, so if we can get a 'yes' from ACPI, we skip it. auto has_i8042_controller = false; - if (ACPI::Parser::the() && ACPI::Parser::the()->have_8042()) - has_i8042_controller = true; - else if (m_i8042_controller->check_existence_via_probing({})) + auto i8042_controller = I8042Controller::initialize(); + switch (kernel_command_line().i8042_presence_mode()) { + case I8042PresenceMode::Automatic: { + // Note: If ACPI is disabled or doesn't indicate that we have an i8042, we + // still perform a manual existence check via probing, which is relevant on + // QEMU, for example. This probing check is known to not work on bare metal + // in all cases, so if we can get a 'yes' from ACPI, we skip it. + if (ACPI::Parser::the() && ACPI::Parser::the()->have_8042()) + has_i8042_controller = true; + else if (i8042_controller->check_existence_via_probing({})) + has_i8042_controller = true; + break; + } + case I8042PresenceMode::Force: { has_i8042_controller = true; + break; + } + case I8042PresenceMode::None: { + break; + } + case I8042PresenceMode::AggressiveTest: { + if (i8042_controller->check_existence_via_probing({})) + has_i8042_controller = true; + break; + } + } // Note: If we happen to not have i8042 just return "gracefully" for now. if (!has_i8042_controller) return {}; + m_i8042_controller = i8042_controller; TRY(m_i8042_controller->detect_devices()); if (m_i8042_controller->mouse()) m_hid_devices.append(m_i8042_controller->mouse().release_nonnull()); -- cgit v1.2.3