]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rust: module: add `module_misc_device` macro
authorWedson Almeida Filho <wedsonaf@google.com>
Fri, 23 Apr 2021 13:50:42 +0000 (14:50 +0100)
committerMiguel Ojeda <ojeda@kernel.org>
Tue, 27 Apr 2021 03:06:13 +0000 (05:06 +0200)
It mimics the C version that allows a module to be defined that exposes
a misc device.

Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
[normalized title]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
rust/kernel/prelude.rs
rust/module.rs

index 06046bf18a4ab1ed2cb13dd912e026d79a664b82..2f8215bc23525d36a5115aaaf8196ff48f177632 100644 (file)
@@ -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};
 
index 076525a97c9e1934f00428270a7a39aefae7cb60..5daa1aee3b598bbf3cfd3a1a287ff2ccb35d1174 100644 (file)
@@ -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<alloc::boxed::Box<kernel::miscdev::Registration>>,
+            }}
+
+            impl kernel::KernelModule for {module} {{
+                fn init() -> kernel::KernelResult<Self> {{
+                    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.")
+}