From edf5833ef8f09661bd04a181d6d3c1190b087327 Mon Sep 17 00:00:00 2001 From: adamrk Date: Sat, 27 Feb 2021 17:42:11 +0100 Subject: [PATCH] Improve docs --- rust/kernel/buffer.rs | 15 ++++ rust/kernel/lib.rs | 2 +- rust/kernel/module_param.rs | 143 +++++++++++++++++++++++++++++++----- 3 files changed, 140 insertions(+), 20 deletions(-) diff --git a/rust/kernel/buffer.rs b/rust/kernel/buffer.rs index ef1525f5b45d78..34b83a9e36091d 100644 --- a/rust/kernel/buffer.rs +++ b/rust/kernel/buffer.rs @@ -1,15 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Struct for writing to a pre-allocated buffer with the [`write!`] macro. +//! +//! [`write!`]: https://doc.rust-lang.org/core/macro.write.html + use core::fmt; +/// A pre-allocated buffer that implements [`core::fmt::Write`]. +/// +/// Consequtive writes will append to what has already been written. +/// Writes that don't fit in the buffer will fail. +/// +/// [`core::fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html pub struct Buffer<'a> { slice: &'a mut [u8], pos: usize, } impl<'a> Buffer<'a> { + /// Create a new buffer from an existing array. pub fn new(slice: &'a mut [u8]) -> Self { Buffer { slice, pos: 0 } } + /// Number of bytes that have already been written to the buffer. + /// This will always be less than the length of the original array. pub fn bytes_written(&self) -> usize { self.pos } diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 7fd2220ead804f..93f0d0979567ef 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -30,7 +30,7 @@ mod allocator; #[doc(hidden)] pub mod bindings; -mod buffer; +pub mod buffer; pub mod c_types; pub mod chrdev; mod error; diff --git a/rust/kernel/module_param.rs b/rust/kernel/module_param.rs index 23823e608a7f37..2ef7d1d9b8aa5b 100644 --- a/rust/kernel/module_param.rs +++ b/rust/kernel/module_param.rs @@ -7,18 +7,34 @@ use core::fmt::Write; /// Types that can be used for module parameters. -/// Note that displaying the type in `sysfs` will fail if `to_string` returns -/// more than `kernel::PAGE_SIZE` bytes (including an additional null terminator). +/// +/// Note that displaying the type in `sysfs` will fail if +/// [`alloc::string::ToString::to_string`] (as implemented through the +/// [`core::fmt::Display`] trait) writes more than `kernel::PAGE_SIZE` +/// bytes (including an additional null terminator). +/// +/// [`alloc::string::ToString::to_string`]: https://doc.rust-lang.org/alloc/string/trait.ToString.html#tymethod.to_string +/// [`core::fmt::Display`]: https://doc.rust-lang.org/core/fmt/trait.Display.html pub trait ModuleParam: core::fmt::Display + core::marker::Sized { + /// Whether the parameter is allowed to be set without an argument. + /// /// Setting this to `true` allows the parameter to be passed without an /// argument (e.g. just `module.param` instead of `module.param=foo`). const NOARG_ALLOWED: bool; + /// Convert a parameter argument into the parameter value. + /// + /// `None` should be returned when parsing of the argument fails. /// `arg == None` indicates that the parameter was passed without an /// argument. If `NOARG_ALLOWED` is set to `false` then `arg` is guaranteed /// to always be `Some(_)`. fn try_from_param_arg(arg: Option<&[u8]>) -> Option; + /// Set the module parameter from a string. + /// + /// Used to set the parameter value when loading the module or when set + /// through `sysfs`. + /// /// # Safety /// /// If `val` is non-null then it must point to a valid null-terminated @@ -42,6 +58,10 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized { } } + /// Write a string representation of the current parameter value to `buf`. + /// + /// Used for displaying the current parameter value in `sysfs`. + /// /// # Safety /// /// `buf` must be a buffer of length at least `kernel::PAGE_SIZE` that is @@ -58,6 +78,10 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized { } } + /// Drop the parameter. + /// + /// Called when unloading a module. + /// /// # Safety /// /// The `arg` field of `param` must be an instance of `Self`. @@ -66,11 +90,16 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized { } } -/// Trait for parsing integers. Strings begining with `0x`, `0o`, or `0b` are -/// parsed as hex, octal, or binary respectively. Strings beginning with `0` -/// otherwise are parsed as octal. Anything else is parsed as decimal. A -/// leading `+` or `-` is also permitted. Any string parsed by `kstrtol` or -/// `kstrtoul` will be successfully parsed. +/// Trait for parsing integers. +/// +/// Strings begining with `0x`, `0o`, or `0b` are parsed as hex, octal, or +/// binary respectively. Strings beginning with `0` otherwise are parsed as +/// octal. Anything else is parsed as decimal. A leading `+` or `-` is also +/// permitted. Any string parsed by [`kstrtol()`] or [`kstrtoul()`] will be +/// successfully parsed. +/// +/// [`kstrtol()`]: https://www.kernel.org/doc/html/latest/core-api/kernel-api.html#c.kstrtol +/// [`kstrtoul()`]: https://www.kernel.org/doc/html/latest/core-api/kernel-api.html#c.kstrtoul trait ParseInt: Sized { fn from_str_radix(src: &str, radix: u32) -> Result; fn checked_neg(self) -> Option; @@ -144,9 +173,30 @@ macro_rules! impl_module_param { }; } +#[macro_export] +/// Generate a static [`kernel_param_ops`](../../../include/linux/moduleparam.h) struct. +/// +/// # Example +/// ```rust +/// make_param_ops!( +/// /// Documentation for new param ops. +/// PARAM_OPS_MYTYPE, // Name for the static. +/// MyType // A type which implements [`ModuleParam`]. +/// ); +/// ``` macro_rules! make_param_ops { ($ops:ident, $ty:ident) => { - /// Generated param ops. + make_param_ops!( + #[doc=""] + $ops, + $ty + ); + }; + ($(#[$meta:meta])* $ops:ident, $ty:ident) => { + $(#[$meta])* + /// + /// Static [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// struct generated by [`make_param_ops`]. pub static $ops: crate::bindings::kernel_param_ops = crate::bindings::kernel_param_ops { flags: if <$ty as crate::module_param::ModuleParam>::NOARG_ALLOWED { crate::bindings::KERNEL_PARAM_OPS_FL_NOARG @@ -171,16 +221,66 @@ impl_module_param!(u64); impl_module_param!(isize); impl_module_param!(usize); -make_param_ops!(PARAM_OPS_I8, i8); -make_param_ops!(PARAM_OPS_U8, u8); -make_param_ops!(PARAM_OPS_I16, i16); -make_param_ops!(PARAM_OPS_U16, u16); -make_param_ops!(PARAM_OPS_I32, i32); -make_param_ops!(PARAM_OPS_U32, u32); -make_param_ops!(PARAM_OPS_I64, i64); -make_param_ops!(PARAM_OPS_U64, u64); -make_param_ops!(PARAM_OPS_ISIZE, isize); -make_param_ops!(PARAM_OPS_USIZE, usize); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`i8`]. + PARAM_OPS_I8, + i8 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`u8`]. + PARAM_OPS_U8, + u8 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`i16`]. + PARAM_OPS_I16, + i16 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`u16`]. + PARAM_OPS_U16, + u16 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`i32`]. + PARAM_OPS_I32, + i32 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`u32`]. + PARAM_OPS_U32, + u32 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`i64`]. + PARAM_OPS_I64, + i64 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`u64`]. + PARAM_OPS_U64, + u64 +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`isize`]. + PARAM_OPS_ISIZE, + isize +); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`usize`]. + PARAM_OPS_USIZE, + usize +); impl ModuleParam for bool { const NOARG_ALLOWED: bool = true; @@ -195,4 +295,9 @@ impl ModuleParam for bool { } } -make_param_ops!(PARAM_OPS_BOOL, bool); +make_param_ops!( + /// Rust implementation of [`kernel_param_ops`](../../../include/linux/moduleparam.h) + /// for [`bool`]. + PARAM_OPS_BOOL, + bool +);