Skip to content

Commit 3ab88e5

Browse files
committed
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 <[email protected]>
1 parent 71082ae commit 3ab88e5

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

rust/kernel/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
pub use alloc::{borrow::ToOwned, string::String};
1515

16-
pub use module::module;
16+
pub use module::{module, module_misc_device};
1717

1818
pub use super::{pr_alert, pr_cont, pr_crit, pr_emerg, pr_err, pr_info, pr_notice, pr_warn};
1919

rust/module.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ pub fn module(ts: TokenStream) -> TokenStream {
641641
}}
642642
643643
fn __init() -> kernel::c_types::c_int {{
644-
match <{type_} as KernelModule>::init() {{
644+
match <{type_} as kernel::KernelModule>::init() {{
645645
Ok(m) => {{
646646
unsafe {{
647647
__MOD = Some(m);
@@ -683,3 +683,82 @@ pub fn module(ts: TokenStream) -> TokenStream {
683683
initcall_section = ".initcall6.init"
684684
).parse().expect("Error parsing formatted string into token stream.")
685685
}
686+
687+
/// Declares a kernel module that exposes a single misc device.
688+
///
689+
/// The `type` argument should be a type which implements the [`FileOpener`] trait. Also accepts
690+
/// various forms of kernel metadata.
691+
///
692+
/// [`FileOpener`]: ../kernel/file_operations/trait.FileOpener.html
693+
///
694+
/// # Examples
695+
///
696+
/// ```rust,no_run
697+
/// use kernel::prelude::*;
698+
///
699+
/// module_misc_device! {
700+
/// type: MyFile,
701+
/// name: b"my_miscdev_kernel_module",
702+
/// author: b"Rust for Linux Contributors",
703+
/// description: b"My very own misc device kernel module!",
704+
/// license: b"GPL v2",
705+
/// }
706+
///
707+
/// #[derive(Default)]
708+
/// struct MyFile;
709+
///
710+
/// impl kernel::file_operations::FileOperations for MyFile {
711+
/// kernel::declare_file_operations!();
712+
/// }
713+
/// ```
714+
#[proc_macro]
715+
pub fn module_misc_device(ts: TokenStream) -> TokenStream {
716+
let mut it = ts.into_iter();
717+
718+
let type_ = get_ident(&mut it, "type");
719+
let name = get_byte_string(&mut it, "name");
720+
let author = get_byte_string(&mut it, "author");
721+
let description = get_byte_string(&mut it, "description");
722+
let license = get_byte_string(&mut it, "license");
723+
expect_end(&mut it);
724+
725+
let module = format!("__internal_ModuleFor{}", type_);
726+
727+
format!(
728+
"
729+
#[doc(hidden)]
730+
struct {module} {{
731+
_dev: core::pin::Pin<alloc::boxed::Box<kernel::miscdev::Registration>>,
732+
}}
733+
734+
impl kernel::KernelModule for {module} {{
735+
fn init() -> kernel::KernelResult<Self> {{
736+
Ok(Self {{
737+
_dev: kernel::miscdev::Registration::new_pinned::<{type_}>(
738+
kernel::cstr!(\"{name}\"),
739+
None,
740+
(),
741+
)?,
742+
}})
743+
}}
744+
}}
745+
746+
kernel::prelude::module! {{
747+
type: {module},
748+
name: b\"{name}\",
749+
author: b\"{author}\",
750+
description: b\"{description}\",
751+
license: b\"{license}\",
752+
params: {{}},
753+
}}
754+
",
755+
module = module,
756+
type_ = type_,
757+
name = name,
758+
author = author,
759+
description = description,
760+
license = license
761+
)
762+
.parse()
763+
.expect("Error parsing formatted string into token stream.")
764+
}

0 commit comments

Comments
 (0)