mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:17:36 +00:00
Kernel: Check i8042 existence before trying to use it
If we don't do so, we just hang forever because we assume there's i8042 controller in the system, which is not a valid assumption for modern PC hardware.
This commit is contained in:
parent
f1f0770d68
commit
dc41a0b830
2 changed files with 39 additions and 0 deletions
|
@ -31,8 +31,30 @@ UNMAP_AFTER_INIT I8042Controller::I8042Controller()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT bool I8042Controller::check_existence()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
SpinlockLocker lock(m_lock);
|
||||||
|
// Note: Perform controller self-test before touching the controller
|
||||||
|
// Try to probe the controller for 5 times and give up if nothing
|
||||||
|
// responded.
|
||||||
|
for (int attempt = 0; attempt < 5; attempt++) {
|
||||||
|
do_write(I8042Port::Command, I8042Command::TestPS2Controller);
|
||||||
|
if (do_read(I8042Port::Buffer) == I8042Response::ControllerTestPassed)
|
||||||
|
return true;
|
||||||
|
// Note: Wait 50 microseconds in case the controller couldn't respond
|
||||||
|
IO::delay(50);
|
||||||
|
}
|
||||||
|
dbgln("I8042: Trying to probe for existence of controller failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void I8042Controller::detect_devices()
|
UNMAP_AFTER_INIT void I8042Controller::detect_devices()
|
||||||
{
|
{
|
||||||
|
if (!check_existence())
|
||||||
|
return;
|
||||||
|
|
||||||
u8 configuration;
|
u8 configuration;
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
|
@ -255,6 +277,18 @@ void I8042Controller::prepare_for_output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void I8042Controller::do_write(u8 port, u8 data)
|
||||||
|
{
|
||||||
|
VERIFY(m_lock.is_locked());
|
||||||
|
IO::out8(port, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT u8 I8042Controller::do_read(u8 port)
|
||||||
|
{
|
||||||
|
VERIFY(m_lock.is_locked());
|
||||||
|
return IO::in8(port);
|
||||||
|
}
|
||||||
|
|
||||||
void I8042Controller::do_wait_then_write(u8 port, u8 data)
|
void I8042Controller::do_wait_then_write(u8 port, u8 data)
|
||||||
{
|
{
|
||||||
VERIFY(m_lock.is_locked());
|
VERIFY(m_lock.is_locked());
|
||||||
|
|
|
@ -144,6 +144,11 @@ private:
|
||||||
u8 do_wait_then_read(u8 port);
|
u8 do_wait_then_read(u8 port);
|
||||||
void drain_output_buffer();
|
void drain_output_buffer();
|
||||||
|
|
||||||
|
// Note: These functions exist only for the initialization process of the controller
|
||||||
|
void do_write(u8 port, u8 data);
|
||||||
|
u8 do_read(u8 port);
|
||||||
|
bool check_existence();
|
||||||
|
|
||||||
Spinlock m_lock;
|
Spinlock m_lock;
|
||||||
bool m_first_port_available { false };
|
bool m_first_port_available { false };
|
||||||
bool m_second_port_available { false };
|
bool m_second_port_available { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue