mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:17:35 +00:00
Kernel/Devices/HID: Propagate errors of HIDDevices properly
Some error indication was done by returning bool. This was changed to propagate the error by ErrorOr from the underlying functions. The returntype of the underlying functions was also changed to propagate the error.
This commit is contained in:
parent
83e96569ed
commit
d3ce97e8b2
8 changed files with 103 additions and 110 deletions
|
@ -164,29 +164,38 @@ UNMAP_AFTER_INIT ErrorOr<void> I8042Controller::detect_devices()
|
||||||
|
|
||||||
// Try to detect and initialize the devices
|
// Try to detect and initialize the devices
|
||||||
if (m_first_port_available) {
|
if (m_first_port_available) {
|
||||||
m_keyboard_device = PS2KeyboardDevice::try_to_initialize(*this);
|
auto error_or_device = PS2KeyboardDevice::try_to_initialize(*this);
|
||||||
if (!m_keyboard_device) {
|
if (error_or_device.is_error()) {
|
||||||
dbgln("I8042: Keyboard device failed to initialize, disable");
|
dbgln("I8042: Keyboard device failed to initialize, disable");
|
||||||
m_first_port_available = false;
|
m_first_port_available = false;
|
||||||
configuration &= ~I8042ConfigurationFlag::FirstPS2PortInterrupt;
|
configuration &= ~I8042ConfigurationFlag::FirstPS2PortInterrupt;
|
||||||
configuration |= I8042ConfigurationFlag::FirstPS2PortClock;
|
configuration |= I8042ConfigurationFlag::FirstPS2PortClock;
|
||||||
|
m_keyboard_device = nullptr;
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration));
|
TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration));
|
||||||
TRY(do_wait_then_write(I8042Port::Buffer, configuration));
|
TRY(do_wait_then_write(I8042Port::Buffer, configuration));
|
||||||
|
} else {
|
||||||
|
m_keyboard_device = error_or_device.release_value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_second_port_available) {
|
if (m_second_port_available) {
|
||||||
m_mouse_device = VMWareMouseDevice::try_to_initialize(*this);
|
auto vmmouse_device_or_error = VMWareMouseDevice::try_to_initialize(*this);
|
||||||
if (!m_mouse_device) {
|
if (vmmouse_device_or_error.is_error()) {
|
||||||
m_mouse_device = PS2MouseDevice::try_to_initialize(*this);
|
// FIXME: is there something to do with the VMWare errors?
|
||||||
if (!m_mouse_device) {
|
auto mouse_device_or_error = PS2MouseDevice::try_to_initialize(*this);
|
||||||
|
if (mouse_device_or_error.is_error()) {
|
||||||
dbgln("I8042: Mouse device failed to initialize, disable");
|
dbgln("I8042: Mouse device failed to initialize, disable");
|
||||||
m_second_port_available = false;
|
m_second_port_available = false;
|
||||||
configuration |= I8042ConfigurationFlag::SecondPS2PortClock;
|
configuration |= I8042ConfigurationFlag::SecondPS2PortClock;
|
||||||
|
m_mouse_device = nullptr;
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration));
|
TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration));
|
||||||
TRY(do_wait_then_write(I8042Port::Buffer, configuration));
|
TRY(do_wait_then_write(I8042Port::Buffer, configuration));
|
||||||
|
} else {
|
||||||
|
m_mouse_device = mouse_device_or_error.release_value();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
m_mouse_device = vmmouse_device_or_error.release_value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,47 +91,39 @@ public:
|
||||||
|
|
||||||
ErrorOr<void> detect_devices();
|
ErrorOr<void> detect_devices();
|
||||||
|
|
||||||
bool reset_device(HIDDevice::Type device)
|
ErrorOr<void> reset_device(HIDDevice::Type device)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_reset_device(device);
|
||||||
if (auto result = do_reset_device(device); result.is_error())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 send_command(HIDDevice::Type device, u8 command)
|
ErrorOr<u8> send_command(HIDDevice::Type device, u8 command)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_send_command(device, command);
|
||||||
return MUST(do_send_command(device, command));
|
|
||||||
}
|
}
|
||||||
u8 send_command(HIDDevice::Type device, u8 command, u8 data)
|
ErrorOr<u8> send_command(HIDDevice::Type device, u8 command, u8 data)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_send_command(device, command, data);
|
||||||
return MUST(do_send_command(device, command, data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 read_from_device(HIDDevice::Type device)
|
ErrorOr<u8> read_from_device(HIDDevice::Type device)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_read_from_device(device);
|
||||||
return MUST(do_read_from_device(device));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_then_write(u8 port, u8 data)
|
ErrorOr<void> wait_then_write(u8 port, u8 data)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_wait_then_write(port, data);
|
||||||
MUST(do_wait_then_write(port, data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 wait_then_read(u8 port)
|
ErrorOr<u8> wait_then_read(u8 port)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// FIXME: Propagate errors properly
|
return do_wait_then_read(port);
|
||||||
return MUST(do_wait_then_read(port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> prepare_for_output();
|
ErrorOr<void> prepare_for_output();
|
||||||
|
|
|
@ -86,23 +86,18 @@ bool PS2KeyboardDevice::handle_irq(const RegisterState&)
|
||||||
return m_i8042_controller->irq_process_input_buffer(HIDDevice::Type::Keyboard);
|
return m_i8042_controller->irq_process_input_buffer(HIDDevice::Type::Keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT RefPtr<PS2KeyboardDevice> PS2KeyboardDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<PS2KeyboardDevice>> PS2KeyboardDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
||||||
{
|
{
|
||||||
auto keyboard_device_or_error = DeviceManagement::try_create_device<PS2KeyboardDevice>(ps2_controller);
|
auto keyboard_device = TRY(DeviceManagement::try_create_device<PS2KeyboardDevice>(ps2_controller));
|
||||||
// FIXME: Find a way to propagate errors
|
|
||||||
VERIFY(!keyboard_device_or_error.is_error());
|
TRY(keyboard_device->initialize());
|
||||||
if (keyboard_device_or_error.value()->initialize())
|
|
||||||
return keyboard_device_or_error.release_value();
|
return keyboard_device;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT bool PS2KeyboardDevice::initialize()
|
UNMAP_AFTER_INIT ErrorOr<void> PS2KeyboardDevice::initialize()
|
||||||
{
|
{
|
||||||
if (!m_i8042_controller->reset_device(HIDDevice::Type::Keyboard)) {
|
return m_i8042_controller->reset_device(HIDDevice::Type::Keyboard);
|
||||||
dbgln("KeyboardDevice: I8042 controller failed to reset device");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices
|
// FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices
|
||||||
|
|
|
@ -23,9 +23,9 @@ class PS2KeyboardDevice final : public IRQHandler
|
||||||
friend class DeviceManagement;
|
friend class DeviceManagement;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static RefPtr<PS2KeyboardDevice> try_to_initialize(const I8042Controller&);
|
static ErrorOr<NonnullRefPtr<PS2KeyboardDevice>> try_to_initialize(const I8042Controller&);
|
||||||
virtual ~PS2KeyboardDevice() override;
|
virtual ~PS2KeyboardDevice() override;
|
||||||
bool initialize();
|
ErrorOr<void> initialize();
|
||||||
|
|
||||||
virtual StringView purpose() const override { return class_name(); }
|
virtual StringView purpose() const override { return class_name(); }
|
||||||
|
|
||||||
|
|
|
@ -137,70 +137,69 @@ MousePacket PS2MouseDevice::parse_data_packet(const RawPacket& raw_packet)
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PS2MouseDevice::get_device_id()
|
ErrorOr<u8> PS2MouseDevice::get_device_id()
|
||||||
{
|
{
|
||||||
if (send_command(I8042Command::GetDeviceID) != I8042Response::Acknowledge)
|
TRY(send_command(I8042Command::GetDeviceID));
|
||||||
return 0;
|
|
||||||
return read_from_device();
|
return read_from_device();
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PS2MouseDevice::read_from_device()
|
ErrorOr<u8> PS2MouseDevice::read_from_device()
|
||||||
{
|
{
|
||||||
return m_i8042_controller->read_from_device(instrument_type());
|
return m_i8042_controller->read_from_device(instrument_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PS2MouseDevice::send_command(u8 command)
|
ErrorOr<u8> PS2MouseDevice::send_command(u8 command)
|
||||||
{
|
{
|
||||||
u8 response = m_i8042_controller->send_command(instrument_type(), command);
|
u8 response = TRY(m_i8042_controller->send_command(instrument_type(), command));
|
||||||
if (response != I8042Response::Acknowledge)
|
|
||||||
|
if (response != I8042Response::Acknowledge) {
|
||||||
dbgln("PS2MouseDevice: Command {} got {} but expected ack: {}", command, response, static_cast<u8>(I8042Response::Acknowledge));
|
dbgln("PS2MouseDevice: Command {} got {} but expected ack: {}", command, response, static_cast<u8>(I8042Response::Acknowledge));
|
||||||
return response;
|
// FIXME: Is this the correct errno value for this?
|
||||||
}
|
return Error::from_errno(EIO);
|
||||||
|
|
||||||
u8 PS2MouseDevice::send_command(u8 command, u8 data)
|
|
||||||
{
|
|
||||||
u8 response = m_i8042_controller->send_command(instrument_type(), command, data);
|
|
||||||
if (response != I8042Response::Acknowledge)
|
|
||||||
dbgln("PS2MouseDevice: Command {} got {} but expected ack: {}", command, response, static_cast<u8>(I8042Response::Acknowledge));
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2MouseDevice::set_sample_rate(u8 rate)
|
|
||||||
{
|
|
||||||
send_command(I8042Command::SetSampleRate, rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT RefPtr<PS2MouseDevice> PS2MouseDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
|
||||||
{
|
|
||||||
auto mouse_device_or_error = DeviceManagement::try_create_device<PS2MouseDevice>(ps2_controller);
|
|
||||||
// FIXME: Find a way to propagate errors
|
|
||||||
VERIFY(!mouse_device_or_error.is_error());
|
|
||||||
if (mouse_device_or_error.value()->initialize())
|
|
||||||
return mouse_device_or_error.release_value();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT bool PS2MouseDevice::initialize()
|
|
||||||
{
|
|
||||||
if (!m_i8042_controller->reset_device(instrument_type())) {
|
|
||||||
dbgln("PS2MouseDevice: I8042 controller failed to reset device");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
u8 device_id = read_from_device();
|
ErrorOr<u8> PS2MouseDevice::send_command(u8 command, u8 data)
|
||||||
|
{
|
||||||
|
u8 response = TRY(m_i8042_controller->send_command(instrument_type(), command, data));
|
||||||
|
if (response != I8042Response::Acknowledge) {
|
||||||
|
dbgln("PS2MouseDevice: Command {} got {} but expected ack: {}", command, response, static_cast<u8>(I8042Response::Acknowledge));
|
||||||
|
// FIXME: Is this the correct errno value for this?
|
||||||
|
return Error::from_errno(EIO);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
if (send_command(I8042Command::SetDefaults) != I8042Response::Acknowledge)
|
ErrorOr<void> PS2MouseDevice::set_sample_rate(u8 rate)
|
||||||
return false;
|
{
|
||||||
|
TRY(send_command(I8042Command::SetSampleRate, rate));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (send_command(I8042Command::EnablePacketStreaming) != I8042Response::Acknowledge)
|
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<PS2MouseDevice>> PS2MouseDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
||||||
return false;
|
{
|
||||||
|
auto mouse_device = TRY(DeviceManagement::try_create_device<PS2MouseDevice>(ps2_controller));
|
||||||
|
TRY(mouse_device->initialize());
|
||||||
|
return mouse_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT ErrorOr<void> PS2MouseDevice::initialize()
|
||||||
|
{
|
||||||
|
TRY(m_i8042_controller->reset_device(instrument_type()));
|
||||||
|
|
||||||
|
u8 device_id = TRY(read_from_device());
|
||||||
|
|
||||||
|
TRY(send_command(I8042Command::SetDefaults));
|
||||||
|
|
||||||
|
TRY(send_command(I8042Command::EnablePacketStreaming));
|
||||||
|
|
||||||
if (device_id != PS2MOUSE_INTELLIMOUSE_ID) {
|
if (device_id != PS2MOUSE_INTELLIMOUSE_ID) {
|
||||||
// Send magical wheel initiation sequence.
|
// Send magical wheel initiation sequence.
|
||||||
set_sample_rate(200);
|
TRY(set_sample_rate(200));
|
||||||
set_sample_rate(100);
|
TRY(set_sample_rate(100));
|
||||||
set_sample_rate(80);
|
TRY(set_sample_rate(80));
|
||||||
device_id = get_device_id();
|
device_id = TRY(get_device_id());
|
||||||
}
|
}
|
||||||
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||||
m_has_wheel = true;
|
m_has_wheel = true;
|
||||||
|
@ -211,17 +210,17 @@ UNMAP_AFTER_INIT bool PS2MouseDevice::initialize()
|
||||||
|
|
||||||
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||||
// Try to enable 5 buttons as well!
|
// Try to enable 5 buttons as well!
|
||||||
set_sample_rate(200);
|
TRY(set_sample_rate(200));
|
||||||
set_sample_rate(200);
|
TRY(set_sample_rate(200));
|
||||||
set_sample_rate(80);
|
TRY(set_sample_rate(80));
|
||||||
device_id = get_device_id();
|
device_id = TRY(get_device_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_id == PS2MOUSE_INTELLIMOUSE_EXPLORER_ID) {
|
if (device_id == PS2MOUSE_INTELLIMOUSE_EXPLORER_ID) {
|
||||||
m_has_five_buttons = true;
|
m_has_five_buttons = true;
|
||||||
dmesgln("PS2MouseDevice: 5 buttons enabled!");
|
dmesgln("PS2MouseDevice: 5 buttons enabled!");
|
||||||
}
|
}
|
||||||
return true;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ class PS2MouseDevice : public IRQHandler
|
||||||
friend class DeviceManagement;
|
friend class DeviceManagement;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static RefPtr<PS2MouseDevice> try_to_initialize(const I8042Controller&);
|
static ErrorOr<NonnullRefPtr<PS2MouseDevice>> try_to_initialize(const I8042Controller&);
|
||||||
bool initialize();
|
ErrorOr<void> initialize();
|
||||||
|
|
||||||
virtual ~PS2MouseDevice() override;
|
virtual ~PS2MouseDevice() override;
|
||||||
|
|
||||||
|
@ -47,12 +47,12 @@ protected:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
u8 read_from_device();
|
ErrorOr<u8> read_from_device();
|
||||||
u8 send_command(u8 command);
|
ErrorOr<u8> send_command(u8 command);
|
||||||
u8 send_command(u8 command, u8 data);
|
ErrorOr<u8> send_command(u8 command, u8 data);
|
||||||
MousePacket parse_data_packet(const RawPacket&);
|
MousePacket parse_data_packet(const RawPacket&);
|
||||||
void set_sample_rate(u8);
|
ErrorOr<void> set_sample_rate(u8);
|
||||||
u8 get_device_id();
|
ErrorOr<u8> get_device_id();
|
||||||
|
|
||||||
u8 m_data_state { 0 };
|
u8 m_data_state { 0 };
|
||||||
RawPacket m_data;
|
RawPacket m_data;
|
||||||
|
|
|
@ -11,18 +11,16 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
UNMAP_AFTER_INIT RefPtr<VMWareMouseDevice> VMWareMouseDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<VMWareMouseDevice>> VMWareMouseDevice::try_to_initialize(const I8042Controller& ps2_controller)
|
||||||
{
|
{
|
||||||
|
// FIXME: return the correct error
|
||||||
if (!VMWareBackdoor::the())
|
if (!VMWareBackdoor::the())
|
||||||
return {};
|
return Error::from_errno(EIO);
|
||||||
if (!VMWareBackdoor::the()->vmmouse_is_absolute())
|
if (!VMWareBackdoor::the()->vmmouse_is_absolute())
|
||||||
return {};
|
return Error::from_errno(EIO);
|
||||||
auto mouse_device_or_error = DeviceManagement::try_create_device<VMWareMouseDevice>(ps2_controller);
|
auto mouse_device = TRY(DeviceManagement::try_create_device<VMWareMouseDevice>(ps2_controller));
|
||||||
// FIXME: Find a way to propagate errors
|
TRY(mouse_device->initialize());
|
||||||
VERIFY(!mouse_device_or_error.is_error());
|
return mouse_device;
|
||||||
if (mouse_device_or_error.value()->initialize())
|
|
||||||
return mouse_device_or_error.release_value();
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMWareMouseDevice::irq_handle_byte_read(u8)
|
void VMWareMouseDevice::irq_handle_byte_read(u8)
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Kernel {
|
||||||
class VMWareMouseDevice final : public PS2MouseDevice {
|
class VMWareMouseDevice final : public PS2MouseDevice {
|
||||||
public:
|
public:
|
||||||
friend class DeviceManagement;
|
friend class DeviceManagement;
|
||||||
static RefPtr<VMWareMouseDevice> try_to_initialize(const I8042Controller&);
|
static ErrorOr<NonnullRefPtr<VMWareMouseDevice>> try_to_initialize(const I8042Controller&);
|
||||||
virtual ~VMWareMouseDevice() override;
|
virtual ~VMWareMouseDevice() override;
|
||||||
|
|
||||||
// ^I8042Device
|
// ^I8042Device
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue