From: Wedson Almeida Filho Date: Fri, 23 Apr 2021 13:50:42 +0000 (+0100) Subject: rust: module: add `module_misc_device` macro X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=40fdb99ad84875e6a427b924abe6a4cecb8bbe56;p=users%2Fjedix%2Flinux-maple.git rust: module: add `module_misc_device` macro It mimics the C version that allows a module to be defined that exposes a misc device. Signed-off-by: Wedson Almeida Filho [normalized title] Signed-off-by: Miguel Ojeda --- diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index 06046bf18a4ab..2f8215bc23525 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -13,7 +13,7 @@ pub use alloc::{borrow::ToOwned, string::String}; -pub use module::module; +pub use module::{module, module_misc_device}; pub use super::{pr_alert, pr_cont, pr_crit, pr_emerg, pr_err, pr_info, pr_notice, pr_warn}; diff --git a/rust/module.rs b/rust/module.rs index 076525a97c9e1..5daa1aee3b598 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -641,7 +641,7 @@ pub fn module(ts: TokenStream) -> TokenStream { }} fn __init() -> kernel::c_types::c_int {{ - match <{type_} as KernelModule>::init() {{ + match <{type_} as kernel::KernelModule>::init() {{ Ok(m) => {{ unsafe {{ __MOD = Some(m); @@ -683,3 +683,82 @@ pub fn module(ts: TokenStream) -> TokenStream { initcall_section = ".initcall6.init" ).parse().expect("Error parsing formatted string into token stream.") } + +/// Declares a kernel module that exposes a single misc device. +/// +/// The `type` argument should be a type which implements the [`FileOpener`] trait. Also accepts +/// various forms of kernel metadata. +/// +/// [`FileOpener`]: ../kernel/file_operations/trait.FileOpener.html +/// +/// # Examples +/// +/// ```rust,no_run +/// use kernel::prelude::*; +/// +/// module_misc_device! { +/// type: MyFile, +/// name: b"my_miscdev_kernel_module", +/// author: b"Rust for Linux Contributors", +/// description: b"My very own misc device kernel module!", +/// license: b"GPL v2", +/// } +/// +/// #[derive(Default)] +/// struct MyFile; +/// +/// impl kernel::file_operations::FileOperations for MyFile { +/// kernel::declare_file_operations!(); +/// } +/// ``` +#[proc_macro] +pub fn module_misc_device(ts: TokenStream) -> TokenStream { + let mut it = ts.into_iter(); + + let type_ = get_ident(&mut it, "type"); + let name = get_byte_string(&mut it, "name"); + let author = get_byte_string(&mut it, "author"); + let description = get_byte_string(&mut it, "description"); + let license = get_byte_string(&mut it, "license"); + expect_end(&mut it); + + let module = format!("__internal_ModuleFor{}", type_); + + format!( + " + #[doc(hidden)] + struct {module} {{ + _dev: core::pin::Pin>, + }} + + impl kernel::KernelModule for {module} {{ + fn init() -> kernel::KernelResult {{ + Ok(Self {{ + _dev: kernel::miscdev::Registration::new_pinned::<{type_}>( + kernel::cstr!(\"{name}\"), + None, + (), + )?, + }}) + }} + }} + + kernel::prelude::module! {{ + type: {module}, + name: b\"{name}\", + author: b\"{author}\", + description: b\"{description}\", + license: b\"{license}\", + params: {{}}, + }} + ", + module = module, + type_ = type_, + name = name, + author = author, + description = description, + license = license + ) + .parse() + .expect("Error parsing formatted string into token stream.") +}