On Sep 30 2024, Werner Sembach wrote:Ok
Am 28.09.24 um 12:05 schrieb Benjamin Tissoires:Not anything you'll notice. BPF is used in network on much more
On Sep 28 2024, Werner Sembach wrote:2 question left on my side:
Hi,Yes. HID-BPF allows to customize a HID device by changing the report
Am 28.09.24 um 09:27 schrieb Benjamin Tissoires:
On Sep 28 2024, Armin Wolf wrote:From just a quick look at
Am 27.09.24 um 23:01 schrieb Pavel Machek:This is exactly why I suggest to make use of HID-BPF. The machine
Hi!
The TUXEDO Sirius 16 Gen1 and TUXEDO Sirius 16 Gen2 devices have a per-keyOk.
controllable RGB keyboard backlight. The firmware API for it is implemented
via WMI.
To make the backlight userspace configurable this driver emulates aPlease don't.
LampArray HID device and translates the input from hidraw to the
corresponding WMI calls. This is a new approach as the leds subsystem lacks
a suitable UAPI for per-key keyboard backlights, and like this no new UAPI
needs to be established.
a) I don't believe emulating crazy HID interface si right thing to
do. (Ton of magic constants. IIRC it stores key positions with
micrometer accuracy or something that crazy. How is userland going to
use this? Will we update micrometers for every single machine?)
specifics is going to be controlled by userspace, leaving out the crazy
bits out of the kernel.
https://www.kernel.org/doc/html/latest/hid/hid-bpf.html HID-BPF is some kind
HID remapping?
descriptor and/or the events, and the requests made from hidraw.
It's a HID -> HID conversion, but controlled by userspace.
See [0] for a tutorial.
But the device in question nativly does not have a hid interface for theYou'll need a thin WMI to HID wrapper, but without LampArray.
backlight. It is controlled via WMI calls.
Afaik userspace on linux has no access to WMI? How could HID-BPF implement
the WMI calls?
Then you load the HID-BPF program from userspace, that program knows
about the specifics of the device, and can do the LampArray transform.
Which means that once the wmi-to-hid driver specific to this device is
built in the kernel, you can adjust your LampArray implementation (the
device specifics micrometers and what not) from usersapce.
Except that your current implementation also does the LampArrayThis is what this driver tries to be.Well, there is not so much about an emulation here. It's a different wayEven if it is,
b) The emulation should go to generic layer, it is not specific to
your hardware.
of presenting the information.
But given that HID LampArray is a HID standard, userspace is able to
implement it once for all the operating systems, which is why this is so
appealing for them. For reference, we have the same issue with SDL and
Steam regarding advanced game controller: they very much prefer to
directly use HID(raw) to talk to the device instead of having a Linux
specific interface.
Also, starting with v6.12, systemd (logind) will be able to provide
hidraw node access to non root applications (in the same way you can
request an input evdev node). So HID LampArray makes a lot of sense IMO.
Maybe introducing a misc-device which provides an ioctl-based API similarYou'll definitely get the API wrong at first, then you'll need to adapt
to the HID LampArray would be a solution?
Basically we would need:
- ioctl for querying the supported LEDs and their properties
- ioctl for enabling/disabling autonomous mode
- ioctl for updating a range of LEDs
- ioctl for updating multiple LEDs at once
for a new device, extend it, etc... But then, you'll depend on one
userspace application that can talk to your custom ioctls, because cross
platform applications will have to implement LampArray, and they'ĺl
probably skip your custom ioctls. And once that userspace application is
gone, you'll still have to maintain this forever.
Also, the application needs to have root access to that misc device, or
you need to add extra support for it in systemd...
If we implement this as a separate subsystem ("illumination subsystem"), then differentAgain, I strongly advise against this.
drivers could use this. This would also allow us to add additional ioctl calls later
for more features.
I'll just reiterate what makes the more sense to me:
- provide a thin wmi-to-hid layer that creates a normal regular HID
device from your device (could be using vendor collections)
conversion. I think it'll make more sense to provide an almost raw
access to the underlying protocol (think of it like your own Tuxedo
vendor collection in HID), and handle the LampArray weirdeness in bpf:
definition of the device physicals, conversion from HID LampArray
commands into Tuxedo specifics.
That's what makes more sense to me at least. Other operating systems- deal with the LampArray bits in the HID stack, that we can reuse forIf a greater efford in the hid stack is planed here i would be all for it.
other devices (I was planing on getting there for my Corsair and
Logitech keyboads).
export the HID nodes directly, so userspace prefers to talk to the
device directly. So I'd rather rely on a standard than trying to fit the
current use case in a new interface that will probably fail.
On my todolist i would try to integrate the leds subsystem with theThat could be done in HID-core as well. Making it part of HID-core also
LampArray interface next, just a simple implementation treating the whole
keyboard as a single led.
means that once we get an actual LampArray device, we'll get support for
it from day one.
Please have a look at the tutorial[0]. That tutorial is missing the- Meanwhile, while prototyping the LampArray support in userspace andI guess i have to do some readup xD.
kernelspace, make use of HID-BPF to transform your vendor protocol
into LampArray. This will allow to fix things without having to
support them forever. This is why HID-BPF exists: so we can create
crazy but safe kernel interfaces, without having to support them
forever.
couple of new hooks you'll need to change the requests emitted from
hidraw as LampArray into Tuxedo, but I can also give you a help into
making it happening.
Basically, you also need to define a .hid_hw_request callback in your
HID_BPF_OPS and extract all of the code you have here into that bpf
program (which is roughly C code).
Cheers,
Benjamin
[0] https://libevdev.pages.freedesktop.org/udev-hid-bpf/tutorial.html
- Does the BPF approach have performance/latency impact?
demanding latency purposes. And IIRC, jumping into BPF is almost a no-op
nowadays. From what I can tell from the BPF maintainer in his ALPSS
presentation last week:
"
BPF C code is compiled into BPF ISA with BPF calling convention,
JIT translate BPF ISA into native ISA,
One to one mapping of BPF registers to x86 registers.
"
Thinking about it, maybe it's not to bad that it only changes once udev is ready, like this udev could decide if leds should be used or if it should directly be passed to OpenRGB for example, giving at least some consistency only changing once: i.e. firmware -> OpenRGB setting and not firmware->leds setting->OpenRGB setting.
- Does it work during boot? (e.g. early control via the leds subsystem toNope. It gets loaded once udev enumerates the device, so unless you
stop firmware induced rainbow puke)
craft a special intird with both the loader and the bpf object it is
not.
However, if that rainbow is bothering you, you can "initialize" the
keyboard to a sane state with your WMI-to-HID driver before exposing the
device to HID.
FWIW, the use of BPF only allows you to not corner yourself. If you
failed at your LampArray implementation, you'll have to deal with it
forever-ish. So it's perfectly sensible to use BPF as an intermediate step
where you develop both userspace and kernel space and then convert back
the BPF into a proper HID driver.
Being able to develop a kernel driver without having to reboot and
being sure you won't crash your kernel is a game changer ;)
Cheers,
Benjamin