diff options
author | Lee Jones <lee@kernel.org> | 2024-12-13 16:47:07 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-12-16 18:12:45 +0300 |
commit | fdb1ac6c302689b286eca9bb7247111bffc7db17 (patch) | |
tree | 47ef15916d285fe8e8c9bcc32ce13e1f817a8052 /samples/rust/rust_misc_device.rs | |
parent | 4a9ce18874068aad0df0bee877d6cdbc26365b30 (diff) | |
download | linux-fdb1ac6c302689b286eca9bb7247111bffc7db17.tar.xz |
samples: rust: Provide example using the new Rust MiscDevice abstraction
This sample driver demonstrates the following basic operations:
* Register a Misc Device
* Create /dev/rust-misc-device
* Provide open call-back for the aforementioned character device
* Operate on the character device via a simple ioctl()
* Provide close call-back for the character device
Signed-off-by: Lee Jones <lee@kernel.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241213134715.601415-3-lee@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'samples/rust/rust_misc_device.rs')
-rw-r--r-- | samples/rust/rust_misc_device.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs new file mode 100644 index 000000000000..324c3696ae3f --- /dev/null +++ b/samples/rust/rust_misc_device.rs @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Rust misc device sample. + +use kernel::{ + c_str, + device::Device, + fs::File, + ioctl::_IO, + miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, + prelude::*, + types::ARef, +}; + +const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80); + +module! { + type: RustMiscDeviceModule, + name: "rust_misc_device", + author: "Lee Jones", + description: "Rust misc device sample", + license: "GPL", +} + +#[pin_data] +struct RustMiscDeviceModule { + #[pin] + _miscdev: MiscDeviceRegistration<RustMiscDevice>, +} + +impl kernel::InPlaceModule for RustMiscDeviceModule { + fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> { + pr_info!("Initialising Rust Misc Device Sample\n"); + + let options = MiscDeviceOptions { + name: c_str!("rust-misc-device"), + }; + + try_pin_init!(Self { + _miscdev <- MiscDeviceRegistration::register(options), + }) + } +} + +struct RustMiscDevice { + dev: ARef<Device>, +} + +#[vtable] +impl MiscDevice for RustMiscDevice { + type Ptr = KBox<Self>; + + fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<KBox<Self>> { + let dev = ARef::from(misc.device()); + + dev_info!(dev, "Opening Rust Misc Device Sample\n"); + + Ok(KBox::new(RustMiscDevice { dev }, GFP_KERNEL)?) + } + + fn ioctl( + me: <Self::Ptr as kernel::types::ForeignOwnable>::Borrowed<'_>, + _file: &File, + cmd: u32, + _arg: usize, + ) -> Result<isize> { + dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n"); + + match cmd { + RUST_MISC_DEV_HELLO => dev_info!(me.dev, "Hello from the Rust Misc Device\n"), + _ => { + dev_err!(me.dev, "-> IOCTL not recognised: {}\n", cmd); + return Err(ENOTTY); + } + } + + Ok(0) + } +} + +impl Drop for RustMiscDevice { + fn drop(&mut self) { + dev_info!(self.dev, "Exiting the Rust Misc Device Sample\n"); + } +} |