diff options
author | Liav A <liavalb@gmail.com> | 2022-12-22 03:46:22 +0200 |
---|---|---|
committer | Jelle Raaijmakers <jelle@gmta.nl> | 2023-01-06 11:09:56 +0100 |
commit | 0f7cc468b2221d54ea79523922a2f21790c02645 (patch) | |
tree | c4925082a1d18b26e3367839a01536daa5792abc /Kernel/Devices | |
parent | fc5bcd84764d60ae18a74a3918d3d0ee6d6a913e (diff) | |
download | serenity-0f7cc468b2221d54ea79523922a2f21790c02645.zip |
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.
Diffstat (limited to 'Kernel/Devices')
-rw-r--r-- | Kernel/Devices/HID/HIDManagement.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
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<void> 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()); |