Kernel: Move HID led handling from keyboard to usb device

Apparently some keyboards can have led control on another interface from
the one where input is received. Now led mask is global to the usb
devices instead of per keyboard instance.
This commit is contained in:
2026-08-22 11:57:19 +03:00
parent f6e841e623
commit 51badd75f0
6 changed files with 151 additions and 136 deletions
+11
View File
@@ -23,6 +23,8 @@ namespace Kernel
virtual void handle_stall(uint8_t endpoint_id) = 0;
virtual void handle_input_data(size_t byte_count, uint8_t endpoint_id) = 0;
virtual bool is_hid_driver() const { return false; }
};
class USBDevice
@@ -62,6 +64,12 @@ namespace Kernel
uint8_t tt_think_time;
};
struct HIDInfo
{
BAN::Atomic<uint32_t> led_mask { 0 };
BAN::Vector<USBClassDriver*> led_controls;
};
public:
USBDevice(USBController& controller, USB::SpeedClass speed_class, uint8_t depth)
: m_controller(controller)
@@ -92,6 +100,8 @@ namespace Kernel
void register_hub_to_init() { m_controller.register_hub_to_init(m_depth + 1); };
void mark_hub_init_done() { m_controller.mark_hub_init_done(m_depth + 1); };
void update_led_mask(uint32_t led_mask);
protected:
void handle_stall(uint8_t endpoint_id);
void handle_input_data(size_t byte_count, uint8_t endpoint_id);
@@ -112,6 +122,7 @@ namespace Kernel
BAN::UniqPtr<DMARegion> m_dma_buffer;
BAN::Vector<BAN::UniqPtr<USBClassDriver>> m_class_drivers;
HIDInfo m_hid_info;
};
}
+19 -2
View File
@@ -74,6 +74,7 @@ namespace Kernel
struct DeviceReport
{
BAN::Vector<USBHID::Report> inputs;
BAN::Vector<USBHID::Report> outputs;
BAN::RefPtr<USBHIDDevice> device;
};
@@ -81,27 +82,43 @@ namespace Kernel
void handle_stall(uint8_t endpoint_id) override;
void handle_input_data(size_t byte_count, uint8_t endpoint_id) override;
bool is_hid_driver() const override { return true; }
USBDevice& device() { return m_device; }
const USBDevice::InterfaceDescriptor& interface() const { return m_interface; }
bool has_led_control() const { return !m_led_controls.empty(); }
void set_leds(uint32_t led_mask);
private:
USBHIDDriver(USBDevice&, const USBDevice::InterfaceDescriptor&);
~USBHIDDriver();
BAN::ErrorOr<void> initialize() override;
BAN::ErrorOr<BAN::Vector<DeviceReport>> initializes_device_reports(const BAN::Vector<USBHID::Collection>&);
BAN::ErrorOr<void> initializes_device_reports(const BAN::Vector<USBHID::Collection>&);
private:
struct LEDControl
{
DeviceReport* report;
uint32_t report_id;
uint32_t report_bits;
};
private:
USBDevice& m_device;
USBDevice::InterfaceDescriptor m_interface;
bool m_uses_report_id { false };
BAN::Vector<DeviceReport> m_device_inputs;
BAN::Vector<DeviceReport> m_device_reports;
uint8_t m_data_endpoint_id = 0;
BAN::UniqPtr<DMARegion> m_data_buffer;
BAN::Vector<LEDControl> m_led_controls;
BAN::UniqPtr<DMARegion> m_led_region;
friend class BAN::UniqPtr<USBHIDDriver>;
};
+1 -10
View File
@@ -11,8 +11,6 @@ namespace Kernel
BAN_NON_MOVABLE(USBKeyboard);
public:
BAN::ErrorOr<void> initialize() override;
void start_report() override;
void stop_report() override;
@@ -23,12 +21,9 @@ namespace Kernel
void update() override;
private:
USBKeyboard(USBHIDDriver& driver, BAN::Vector<USBHID::Report>&& outputs);
USBKeyboard(USBHIDDriver& driver);
~USBKeyboard() = default;
void set_leds(uint16_t mask);
void set_leds(uint8_t report_id, uint16_t mask);
private:
USBHIDDriver& m_driver;
@@ -38,11 +33,7 @@ namespace Kernel
BAN::Array<bool, 0x100> m_keyboard_state { false };
BAN::Array<bool, 0x100> m_keyboard_state_temp { false };
uint16_t m_toggle_mask { 0 };
uint16_t m_led_mask { 0 };
BAN::UniqPtr<DMARegion> m_led_region;
BAN::Vector<USBHID::Report> m_outputs;
BAN::Optional<uint8_t> m_repeat_scancode;
uint8_t m_repeat_modifier { 0 };