From patchwork Thu Mar 13 16:03:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Rameshbabu X-Patchwork-Id: 14015370 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BFF0C282EC for ; Thu, 13 Mar 2025 16:11:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6B17510E8E3; Thu, 13 Mar 2025 16:11:21 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=protonmail.com header.i=@protonmail.com header.b="f4j+wNB2"; dkim-atps=neutral X-Greylist: delayed 448 seconds by postgrey-1.36 at gabe; Thu, 13 Mar 2025 16:11:19 UTC Received: from mail-4327.protonmail.ch (mail-4327.protonmail.ch [185.70.43.27]) by gabe.freedesktop.org (Postfix) with ESMTPS id DB8CA10E8E3 for ; Thu, 13 Mar 2025 16:11:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1741881820; x=1742141020; bh=xILv2bEEr10gYM5OUsCRiMfhcplESrJ2O+L7nHoU4zg=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=f4j+wNB21WzE3L5Ph1e8pChHKhXPBo+AFNQzD7q+ooSOSaBXb1bDyD4kVt7hlPF3p uk8vaTFYyMuE87LI0Wm89b521or8Z/gN/u8HGN56xZ5kT5Nh+MLs0UiEmGMkxXItv7 MvRsSCDECzqWnAnFAo9vzXVnxSA9vxBlzz5ChqxDFu0Zqe1vTSKXC4uTPNvZZeNAPu bOOtjVzRhKJFRVSxBOnUAn+YIk0tQvPk5kgeU8S1HlFPJXMumiYZ87EBY5GoVun0BG di3zMKeE514rM2FeJgUYJcMAmfADqZmyH+GTtxjyhAZaWG3gBzAkN+Btr2ZAQK6Bqw 7o11GqWn/kVIQ== Date: Thu, 13 Mar 2025 16:03:35 +0000 To: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-input@vger.kernel.org, dri-devel@lists.freedesktop.org From: Rahul Rameshbabu Cc: Jiri Kosina , Benjamin Tissoires , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Rahul Rameshbabu Subject: [PATCH RFC 1/3] rust: core abstractions for HID drivers Message-ID: <20250313160220.6410-4-sergeantsagara@protonmail.com> In-Reply-To: <20250313160220.6410-2-sergeantsagara@protonmail.com> References: <20250313160220.6410-2-sergeantsagara@protonmail.com> Feedback-ID: 26003777:user:proton X-Pm-Message-ID: 58e5f15e4d4b1f3f057aaf90b658d81faaf96ccb MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" These abstractions enable the development of HID drivers in Rust by binding with the HID core C API. They provide Rust types that map to the equivalents in C. In this initial draft, only hid_device and hid_device_id are provided direct Rust type equivalents. hid_driver is specially wrapped with a custom Driver type. The module_hid_driver! macro provides analogous functionality to its C equivalent. Future work for these abstractions would include more bindings for common HID-related types, such as hid_field, hid_report_enum, and hid_report. Providing Rust equivalents to useful core HID functions will also be necessary for HID driver development in Rust. Some concerns with this initial draft - The need for a DeviceId and DeviceIdShallow type. + DeviceIdShallow is used to guarantee the safety requirement for the Sync trait. - The create_hid_driver call in the module_hid_driver! macro does not use Pin semantics for passing the ID_TABLE. I could not get Pin semantics to work in a const fn. I get a feeling this might be safe but need help reviewing this. Signed-off-by: Rahul Rameshbabu --- drivers/hid/Kconfig | 8 ++ rust/bindings/bindings_helper.h | 1 + rust/kernel/hid.rs | 245 ++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 2 + 4 files changed, 256 insertions(+) create mode 100644 rust/kernel/hid.rs diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b53eb569bd49..e085964c7ffc 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -714,6 +714,14 @@ config HID_MEGAWORLD_FF Say Y here if you have a Mega World based game controller and want to have force feedback support for it. +config RUST_HID_ABSTRACTIONS + bool "Rust HID abstractions support" + depends on RUST + depends on HID=y + help + Adds support needed for HID drivers written in Rust. It provides a + wrapper around the C hid core. + config HID_REDRAGON tristate "Redragon keyboards" default !EXPERT diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index 55354e4dec14..e2e95afe9f4a 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/hid.rs b/rust/kernel/hid.rs new file mode 100644 index 000000000000..f13476b49e7d --- /dev/null +++ b/rust/kernel/hid.rs @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2025 Rahul Rameshbabu + +use crate::{error::*, prelude::*, types::Opaque}; +use core::marker::PhantomData; + +#[repr(transparent)] +pub struct Device(Opaque); + +impl Device { + unsafe fn from_ptr<'a>(ptr: *mut bindings::hid_device) -> &'a mut Self { + let ptr = ptr.cast::(); + + unsafe { &mut *ptr } + } + + pub fn vendor(&self) -> u32 { + let hdev = self.0.get(); + + unsafe { (*hdev).vendor } + } + + pub fn product(&self) -> u32 { + let hdev = self.0.get(); + + unsafe { (*hdev).product } + } +} + +#[repr(transparent)] +pub struct DeviceIdShallow(Opaque); + +// SAFETY: `DeviceIdShallow` doesn't expose any &self method to access internal data, so it's safe to +// share `&DriverVTable` across execution context boundaries. +unsafe impl Sync for DeviceIdShallow {} + +impl DeviceIdShallow { + pub const fn new() -> Self { + DeviceIdShallow(Opaque::new(bindings::hid_device_id { + // SAFETY: The rest is zeroed out to initialize `struct hid_device_id`, + // sets `Option<&F>` to be `None`. + ..unsafe { ::core::mem::MaybeUninit::::zeroed().assume_init() } + })) + } + + pub const fn new_usb(vendor: u32, product: u32) -> Self { + DeviceIdShallow(Opaque::new(bindings::hid_device_id { + bus: 0x3, /* BUS_USB */ + vendor: vendor, + product: product, + // SAFETY: The rest is zeroed out to initialize `struct hid_device_id`, + // sets `Option<&F>` to be `None`. + ..unsafe { ::core::mem::MaybeUninit::::zeroed().assume_init() } + })) + } + + const unsafe fn as_ptr(&self) -> *const bindings::hid_device_id { + self.0.get() + } +} + +#[repr(transparent)] +pub struct DeviceId(Opaque); + +impl DeviceId { + unsafe fn from_ptr<'a>(ptr: *mut bindings::hid_device_id) -> &'a mut Self { + let ptr = ptr.cast::(); + + unsafe { &mut *ptr } + } + + unsafe fn from_const_ptr<'a>(ptr: *const bindings::hid_device_id) -> &'a Self { + let ptr = ptr.cast::(); + + unsafe { &(*ptr) } + } + + pub fn vendor(&self) -> u32 { + let hdev_id = self.0.get(); + + unsafe { (*hdev_id).vendor } + } + + pub fn product(&self) -> u32 { + let hdev_id = self.0.get(); + + unsafe { (*hdev_id).product } + } +} + +/* +#[repr(transparent)] +pub struct Field(Opaque); + +#[repr(transparent)] +pub struct ReportEnum(Opaque); + +#[repr(transparent)] +pub struct Report(Opaque); +*/ + +#[vtable] +pub trait Driver { + fn probe(_dev: &mut Device, _id: &DeviceId) -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + + fn remove(_dev: &mut Device) { + } +} + +struct Adapter { + _p: PhantomData, +} + +impl Adapter { + unsafe extern "C" fn probe_callback( + hdev: *mut bindings::hid_device, + hdev_id: *const bindings::hid_device_id, + ) -> crate::ffi::c_int { + from_result(|| { + let dev = unsafe { Device::from_ptr(hdev) }; + let dev_id = unsafe { DeviceId::from_const_ptr(hdev_id) }; + T::probe(dev, dev_id)?; + Ok(0) + }) + } + + unsafe extern "C" fn remove_callback(hdev: *mut bindings::hid_device) { + let dev = unsafe { Device::from_ptr(hdev) }; + T::remove(dev); + } +} + +#[repr(transparent)] +pub struct DriverVTable(Opaque); + +// SAFETY: `DriverVTable` doesn't expose any &self method to access internal data, so it's safe to +// share `&DriverVTable` across execution context boundaries. +unsafe impl Sync for DriverVTable {} + +pub const fn create_hid_driver( + name: &'static CStr, + id_table: &'static DeviceIdShallow, +) -> DriverVTable { + DriverVTable(Opaque::new(bindings::hid_driver { + name: name.as_char_ptr().cast_mut(), + id_table: unsafe { id_table.as_ptr() }, + probe: if T::HAS_PROBE { + Some(Adapter::::probe_callback) + } else { + None + }, + remove: if T::HAS_REMOVE { + Some(Adapter::::remove_callback) + } else { + None + }, + // SAFETY: The rest is zeroed out to initialize `struct hid_driver`, + // sets `Option<&F>` to be `None`. + ..unsafe { core::mem::MaybeUninit::::zeroed().assume_init() } + })) +} + +pub struct Registration { + driver: Pin<&'static mut DriverVTable>, +} + +unsafe impl Send for Registration {} + +impl Registration { + pub fn register( + module: &'static crate::ThisModule, + driver: Pin<&'static mut DriverVTable>, + name: &'static CStr, + ) -> Result { + to_result(unsafe { + bindings::__hid_register_driver(driver.0.get(), module.0, name.as_char_ptr()) + })?; + + Ok(Registration { driver }) + } +} + +impl Drop for Registration { + fn drop(&mut self) { + unsafe { + bindings::hid_unregister_driver(self.driver.0.get()) + }; + } +} + +#[macro_export] +macro_rules! usb_device { + (vendor: $vendor:expr, product: $product:expr $(,)?) => { + $crate::hid::DeviceIdShallow::new_usb($vendor, $product) + } +} + +#[macro_export] +macro_rules! module_hid_driver { + (@replace_expr $_t:tt $sub:expr) => {$sub}; + + (@count_devices $($x:expr),*) => { + 0usize $(+ $crate::module_hid_driver!(@replace_expr $x 1usize))* + }; + + (driver: $driver:ident, id_table: [$($dev_id:expr),+ $(,)?], name: $name:tt, $($f:tt)*) => { + struct Module { + _reg: $crate::hid::Registration, + } + + $crate::prelude::module! { + type: Module, + name: $name, + $($f)* + } + + const _: () = { + static NAME: &$crate::str::CStr = $crate::c_str!($name); + + static ID_TABLE: [$crate::hid::DeviceIdShallow; + $crate::module_hid_driver!(@count_devices $($dev_id),+) + 1] = [ + $($dev_id),+, + $crate::hid::DeviceIdShallow::new(), + ]; + + static mut DRIVER: $crate::hid::DriverVTable = + $crate::hid::create_hid_driver::<$driver>(NAME, unsafe { &ID_TABLE[0] }); + + impl $crate::Module for Module { + fn init(module: &'static $crate::ThisModule) -> Result { + let driver = unsafe { &mut DRIVER }; + let mut reg = $crate::hid::Registration::register( + module, + ::core::pin::Pin::static_mut(driver), + NAME, + )?; + Ok(Module { _reg: reg }) + } + } + }; + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 496ed32b0911..51b8c2689264 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -49,6 +49,8 @@ #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] pub mod firmware; pub mod fs; +#[cfg(CONFIG_RUST_HID_ABSTRACTIONS)] +pub mod hid; pub mod init; pub mod io; pub mod ioctl; From patchwork Thu Mar 13 16:03:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Rameshbabu X-Patchwork-Id: 14015358 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7C56CC282EC for ; Thu, 13 Mar 2025 16:04:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DCFCB10E23E; Thu, 13 Mar 2025 16:04:21 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=protonmail.com header.i=@protonmail.com header.b="o5i2Bx8l"; dkim-atps=neutral Received: from mail-106110.protonmail.ch (mail-106110.protonmail.ch [79.135.106.110]) by gabe.freedesktop.org (Postfix) with ESMTPS id 09B6F10E23E for ; Thu, 13 Mar 2025 16:04:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1741881837; x=1742141037; bh=22zAQyvnoEOXs6L3ERiAc9u5WNizLjpTOmo46XmcJiY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=o5i2Bx8lA7arvA20I7jVUHWSilwKv050lggyYw0HxiyUcIWVLXnxE4VfS5A5Fsfdb H5CPVTErXtHm0lC0b8GQUJf+iptFmC5W3VpeZSzTDOYjQlwYcCQ/qQLUBzytTz1o4R QszkhD262fUdq+gmHVbTz7kCay1RU3WWFMvlmzqZJoqwzwvAnvzWQur5qPccO2Y5e8 zrUvzXQLqMjau9HeJhZAZBfaQkqMBl8QNKHg3NyYvg0j1XqSm3VO6Hkb6gR5+ltNLR U5RM/+MeXHyVOguQ02DzTxUbx9zBMRew9cj1Qysb0wdCD6vDpXWG6l5HZKeg0sZvDm EtAbHD5LW+3ng== Date: Thu, 13 Mar 2025 16:03:51 +0000 To: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-input@vger.kernel.org, dri-devel@lists.freedesktop.org From: Rahul Rameshbabu Cc: Jiri Kosina , Benjamin Tissoires , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Rahul Rameshbabu , Julius Zint Subject: [PATCH RFC 2/3] rust: hid: USB Monitor Control Class driver Message-ID: <20250313160220.6410-5-sergeantsagara@protonmail.com> In-Reply-To: <20250313160220.6410-2-sergeantsagara@protonmail.com> References: <20250313160220.6410-2-sergeantsagara@protonmail.com> Feedback-ID: 26003777:user:proton X-Pm-Message-ID: b1713685ae05b35e392bda64f74117df38fd9c74 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This code will eventually contain the logic needed to drive the backlight of displays that implement the USB Monitor Control Class specification. Examples include the Apple Studio Display and Apple Pro Display XDR monitors. USB Monitor Control Class encompasses more than just backlight control, so the driver could be further extended as monitors support more functionality in the specification. This code is a skeleton currently, where the focus right now is on the core Rust API. The driver skeleton was written before approaching the Rust API and C binding work. This was done to provide a guide for what the Rust API should look like and avoid any rough C binding work from being exposed to Rust HID device drivers. To go forward with this driver for the purpose of external monitor backlight control, a new DRM backlight API that is scoped per connector will be required. I am currently in the process of developing this new API. I document the details in my related blog posts. The issue with the current backlight API is it was designed on the assumption that only internal panels have controllable backlights. Using this assumption combined with another that there can only ever be a single internal panel, having more than one device register with the backlight interface would confuse userspace applications. Julius Zint originally tried to implement such a driver a bit more than a year ago with a C driver but was blocked by the limitations of the backlight API. I asked him for permission to continue the work in Rust while accrediting him for the HID report parsing logic for the backlight support in the USB Monitor Control Class specification. Cc: Julius Zint Link: https://lore.kernel.org/lkml/20230820094118.20521-1-julius@zint.sh/ Link: https://binary-eater.github.io/posts/linux_usb_monitor_control/ Link: https://www.usb.org/sites/default/files/usbmon11.pdf Signed-off-by: Rahul Rameshbabu --- drivers/hid/Kconfig | 8 +++++++ drivers/hid/Makefile | 1 + drivers/hid/hid_monitor_control.rs | 37 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 drivers/hid/hid_monitor_control.rs diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e085964c7ffc..92be13acb956 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -722,6 +722,14 @@ config RUST_HID_ABSTRACTIONS Adds support needed for HID drivers written in Rust. It provides a wrapper around the C hid core. +config HID_MONITOR_CONTROL + tristate "USB Monitor Control Class support" + depends on USB_HID + depends on RUST_HID_ABSTRACTIONS + help + Say Y here if you want to enable control over a monitor that uses USB + Monitor Control Class. + config HID_REDRAGON tristate "Redragon keyboards" default !EXPERT diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 482b096eea28..bf8b096bcf23 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_HID_MCP2221) += hid-mcp2221.o obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o obj-$(CONFIG_HID_MEGAWORLD_FF) += hid-megaworld.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o +obj-$(CONFIG_HID_MONITOR_CONTROL) += hid_monitor_control.o obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o obj-$(CONFIG_HID_NINTENDO) += hid-nintendo.o diff --git a/drivers/hid/hid_monitor_control.rs b/drivers/hid/hid_monitor_control.rs new file mode 100644 index 000000000000..18afd69a56d5 --- /dev/null +++ b/drivers/hid/hid_monitor_control.rs @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2025 Rahul Rameshbabu + +use kernel::prelude::*; +use kernel::hid::{ + self, + Driver, +}; + +struct HidMonitorControl; + +#[vtable] +impl Driver for HidMonitorControl { + fn probe(dev: &mut hid::Device, id: &hid::DeviceId) -> Result<()> { + /* TODO implement */ + Ok(()) + } + + fn remove(dev: &mut hid::Device) { + /* TODO implement */ + } +} + +kernel::module_hid_driver! { + driver: HidMonitorControl, + id_table: [ + kernel::usb_device! { + vendor: /* TODO fill in */, + product: /* TODO fill in */, + }, + ], + name: "monitor_control", + author: "Rahul Rameshbabu ", + description: "Driver for the USB Monitor Control Class", + license: "GPL", +} From patchwork Thu Mar 13 16:04:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Rameshbabu X-Patchwork-Id: 14015357 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69BF6C282EC for ; Thu, 13 Mar 2025 16:04:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D61CC10E23B; Thu, 13 Mar 2025 16:04:16 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=protonmail.com header.i=@protonmail.com header.b="OdoSv+Fs"; dkim-atps=neutral Received: from mail-41103.protonmail.ch (mail-41103.protonmail.ch [185.70.41.103]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8897A10E23B for ; Thu, 13 Mar 2025 16:04:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1741881845; x=1742141045; bh=zJzfYxqTGkpvxERVV5xc7MvB+YJR4f+zoVmRta1ZEMc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=OdoSv+FsaUzHNvgKe8WkVvrVYmpgRJUbIw/9WlM2oG8d+T+VpA/us+gkkYvVptNnO mTJ+gkIiQ3QRtGFb1QmFTYp8i+fO1czeq8VB6YSt944F1ItXw5bvdpluoNL5ZkHB88 /Q9AyULSgoc6oi3OH0LvxzFn8GnjYAO26b6WrRTed2iw20yIK+Be+p3XABQY3nsHjR 4nqzW9a2V11V+ewo5fw3Ay2tRam5qC/URzDixgkJhyxmwtiTNwxwfIquqOE8EzjWzr bjTYn/vPG+LZX8PP+WXYnVJcFmYyuD2t+NKHZBeluSH2rwljPBaDhmVIbXvN5rhBqO w6TQEEPDBvW6w== Date: Thu, 13 Mar 2025 16:04:00 +0000 To: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-input@vger.kernel.org, dri-devel@lists.freedesktop.org From: Rahul Rameshbabu Cc: Jiri Kosina , Benjamin Tissoires , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Rahul Rameshbabu Subject: [PATCH RFC 3/3] rust: hid: demo the core abstractions for probe and remove Message-ID: <20250313160220.6410-6-sergeantsagara@protonmail.com> In-Reply-To: <20250313160220.6410-2-sergeantsagara@protonmail.com> References: <20250313160220.6410-2-sergeantsagara@protonmail.com> Feedback-ID: 26003777:user:proton X-Pm-Message-ID: b638180c65cc3d8ba015ced71bcec205a97bd6d0 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This is a very basic "hello, world!" implementation to illustrate that the probe and remove callbacks are working as expected. I chose an arbitrary device I had on hand for populating in the HID device id table. [ +0.012968] monitor_control: Probing HID device vendor: 2389 product: 29204 using Rust! [ +0.000108] monitor_control: Removing HID device vendor: 2389 product: 29204 using Rust! Signed-off-by: Rahul Rameshbabu --- drivers/hid/hid_monitor_control.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid_monitor_control.rs b/drivers/hid/hid_monitor_control.rs index 18afd69a56d5..aeb6e4058a6b 100644 --- a/drivers/hid/hid_monitor_control.rs +++ b/drivers/hid/hid_monitor_control.rs @@ -8,17 +8,22 @@ Driver, }; +const USB_VENDOR_ID_NVIDIA: u32 = 0x0955; +const USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER: u32 = 0x7214; + struct HidMonitorControl; #[vtable] impl Driver for HidMonitorControl { fn probe(dev: &mut hid::Device, id: &hid::DeviceId) -> Result<()> { /* TODO implement */ + pr_info!("Probing HID device vendor: {} product: {} using Rust!\n", id.vendor(), id.product()); Ok(()) } fn remove(dev: &mut hid::Device) { /* TODO implement */ + pr_info!("Removing HID device vendor: {} product: {} using Rust!\n", dev.vendor(), dev.product()); } } @@ -26,8 +31,8 @@ fn remove(dev: &mut hid::Device) { driver: HidMonitorControl, id_table: [ kernel::usb_device! { - vendor: /* TODO fill in */, - product: /* TODO fill in */, + vendor: USB_VENDOR_ID_NVIDIA, + product: USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER, }, ], name: "monitor_control",