From: Danilo Krummrich <dakr@kernel.org>
To: Rahul Rameshbabu <sergeantsagara@protonmail.com>
Cc: linux-input@vger.kernel.org, rust-for-linux@vger.kernel.org,
"Benjamin Tissoires" <bentiss@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Daniel Brooks" <db48x@db48x.net>,
"Jiri Kosina" <jikos@kernel.org>
Subject: Re: [PATCH v1 2/3] rust: core abstractions for HID drivers
Date: Sun, 29 Jun 2025 10:45:44 +0200 [thread overview]
Message-ID: <aGD9OIZ_xE6h3199@pollux> (raw)
In-Reply-To: <20250629045031.92358-4-sergeantsagara@protonmail.com>
(Cc: +Jiri)
On Sun, Jun 29, 2025 at 04:51:15AM +0000, Rahul Rameshbabu wrote:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3f7fbd0d67a..487750d9fd1e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10686,6 +10686,13 @@ F: include/uapi/linux/hid*
> F: samples/hid/
> F: tools/testing/selftests/hid/
>
> +HID CORE LAYER [RUST]
> +M: Rahul Rameshbabu <sergeantsagara@protonmail.com>
> +L: linux-input@vger.kernel.org
> +S: Maintained
> +T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
> +F: rust/kernel/hid.rs
I assume this is agreed with the HID CORE LAYER maintainers?
There are multiple possible options, for instance:
1) Maintain the Rust abstractions as part of the existing MAINTAINERS entry.
Optionally, the author can be added as another maintainer or reviewer.
2) Add a separate MAINTAINERS entry; patches still go through the same
subsystem tree.
3) Add a separate MAINTAINERS entry; patches don't go through the subsystem
tree (e.g. because the subsystem maintainers don't want to deal with it).
I usually recommend (1), but that's of course up to you and the HID maintainers.
Here it seems you want to go with option (2). Given that I recommend to add the
HID maintainers as reviewers (if they like) to the new MAINTAINERS entry, so
they can easily follow on what's going on.
> +/// The HID driver trait.
> +///
> +/// # Example
> +///
> +///```
> +/// use kernel::hid;
> +///
> +/// const USB_VENDOR_ID_VALVE: u32 = 0x28de;
> +/// const USB_DEVICE_ID_STEAM_DECK: u32 = 0x1205;
I think we should make the existing constants from drivers/hid/hid-ids.h
available, rather than defining them again.
<snip>
> +pub trait Driver: Send {
> + /// The type holding information about each device id supported by the driver.
> + // TODO: Use `associated_type_defaults` once stabilized:
> + //
> + // ```
> + // type IdInfo: 'static = ();
> + // ```
> + type IdInfo: 'static;
> +
> + /// The table of device ids supported by the driver.
> + const ID_TABLE: IdTable<Self::IdInfo>;
> +
> + /// Called before report descriptor parsing. Can be used to mutate the
> + /// report descriptor before the core HID logic processes the descriptor.
> + /// Useful for problematic report descriptors that prevent HID devices from
> + /// functioning correctly.
> + ///
> + /// Optional to implement.
> + fn report_fixup<'a, 'b: 'a>(_hdev: &Device, _rdesc: &'b mut [u8]) -> &'a [u8] {
report_fixup() is a bus device callback and seems to be synchronized against
other bus device callbacks, hence the device argument should be
&Device<device::Core>.
> + build_error!(VTABLE_DEFAULT_ERROR)
> + }
> +}
> +
> +/// An adapter for the registration of HID drivers.
> +pub struct Adapter<T: Driver>(T);
> +
> +// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
> +// a preceding call to `register` has been successful.
> +unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
> + type RegType = bindings::hid_driver;
> +
> + unsafe fn register(
> + hdrv: &Opaque<Self::RegType>,
> + name: &'static CStr,
> + module: &'static ThisModule,
> + ) -> Result {
> + // SAFETY: It's safe to set the fields of `struct hid_driver` on initialization.
> + let raw_hdrv = unsafe { &mut *hdrv.get() };
I don't think you can guarantee that all fields of `hdrv` are properly
initialized to create this mutable reference. I think you should do what PCI and
platform does instead.
> +impl<T: Driver + 'static> Adapter<T> {
> + extern "C" fn report_fixup_callback(
> + hdev: *mut bindings::hid_device,
> + buf: *mut u8,
> + size: *mut kernel::ffi::c_uint,
> + ) -> *const u8 {
> + // SAFETY: The HID subsystem only ever calls the report_fixup callback
> + // with a valid pointer to a `struct hid_device`.
> + //
> + // INVARIANT: `hdev` is valid for the duration of
> + // `report_fixup_callback()`.
> + let hdev = unsafe { &*hdev.cast::<Device>() };
::<Device<device::Core>
> +
> + // SAFETY: The HID subsystem only ever calls the report_fixup callback
> + // with a valid pointer to a `kernel::ffi::c_uint`.
> + //
> + // INVARIANT: `size` is valid for the duration of
> + // `report_fixup_callback()`.
> + let buf_len: usize = match unsafe { *size }.try_into() {
> + Ok(len) => len,
> + Err(e) => {
> + pr_err!(
> + "Cannot fix report description due to length conversion failure: {}!\n",
> + e
> + );
You have a valid device at this point, please use it to print with dev_err!().
> +
> + return buf;
> + }
> + };
> +
> + // Build a mutable Rust slice from buf and size
> + //
> + // SAFETY: The HID subsystem only ever calls the report_fixup callback
> + // with a valid pointer to a `u8` buffer.
> + //
> + // INVARIANT: `buf` is valid for the duration of
> + // `report_fixup_callback()`.
> + let rdesc_slice = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) };
> + let rdesc_slice = T::report_fixup(hdev, rdesc_slice);
> +
> + match rdesc_slice.len().try_into() {
> + // SAFETY: The HID subsystem only ever calls the report_fixup
> + // callback with a valid pointer to a `kernel::ffi::c_uint`.
> + //
> + // INVARIANT: `size` is valid for the duration of
> + // `report_fixup_callback()`.
> + Ok(len) => unsafe { *size = len },
> + Err(e) => {
> + pr_err!("Fixed report description will not be used due to {}!\n", e);
Same here.
> +
> + return buf;
> + }
> + }
> +
> + rdesc_slice.as_ptr()
> + }
> +}
You also need to call the macros that generate the device context Deref
hierarchy and ARef<Device> conversion for you, i.e.
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
// argument.
kernel::impl_device_context_deref!(unsafe { Device });
kernel::impl_device_context_into_aref!(Device);
You probably don't need that latter, given that the only bus callback you
implement is report_fixup() and you don't implement AlwaysRefCounted for Device
yet.
next prev parent reply other threads:[~2025-06-29 8:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-29 4:51 [PATCH v1 0/3] Initial work for Rust abstraction for HID device driver development Rahul Rameshbabu
2025-06-29 4:51 ` [PATCH v1 1/3] HID: core: Change hid_driver to use a const char* for name Rahul Rameshbabu
2025-06-29 4:51 ` [PATCH v1 2/3] rust: core abstractions for HID drivers Rahul Rameshbabu
2025-06-29 8:45 ` Danilo Krummrich [this message]
2025-07-03 6:37 ` Jiri Kosina
2025-07-03 8:01 ` Benjamin Tissoires
2025-07-03 8:20 ` Danilo Krummrich
2025-07-05 7:31 ` Rahul Rameshbabu
2025-07-05 10:41 ` Miguel Ojeda
2025-07-06 3:03 ` Rahul Rameshbabu
2025-07-05 10:54 ` Danilo Krummrich
2025-06-29 4:51 ` [PATCH v1 3/3] rust: hid: Glorious Gaming PC Race Model O and O- mice reference driver Rahul Rameshbabu
2025-06-29 9:22 ` Danilo Krummrich
2025-07-03 10:36 ` Peter Hutterer
2025-07-05 13:01 ` [PATCH v1 0/3] Initial work for Rust abstraction for HID device driver development Aditya Garg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aGD9OIZ_xE6h3199@pollux \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bentiss@kernel.org \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=db48x@db48x.net \
--cc=gary@garyguo.net \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sergeantsagara@protonmail.com \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.