Skip to content

Commit

Permalink
Improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
adamrk committed Feb 27, 2021
1 parent 923540b commit edf5833
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 20 deletions.
15 changes: 15 additions & 0 deletions rust/kernel/buffer.rs
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
143 changes: 124 additions & 19 deletions rust/kernel/module_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self>;

/// 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
Expand All @@ -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
Expand All @@ -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`.
Expand All @@ -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<Self, core::num::ParseIntError>;
fn checked_neg(self) -> Option<Self>;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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
);

0 comments on commit edf5833

Please sign in to comment.