Skip to content

Commit 6c9036e

Browse files
committed
Add NO_ARG and bool ops
1 parent b504961 commit 6c9036e

File tree

2 files changed

+54
-10
lines changed

2 files changed

+54
-10
lines changed

rust/kernel/module_param.rs

+53-9
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@ use core::fmt::Write;
44
/// Note that displaying the type in `sysfs` will fail if `to_string` returns
55
/// more than `kernel::PAGE_SIZE` bytes (including an additional null terminator).
66
pub trait ModuleParam : core::fmt::Display + core::marker::Sized {
7-
fn try_from_param_arg(arg: &[u8]) -> Option<Self>;
7+
/// Setting this to `true` allows the parameter to be passed without an
8+
/// argument (e.g. just `module.param` instead of `module.param=foo`).
9+
const NOARG_ALLOWED: bool;
10+
11+
/// `arg == None` indicates that the parameter was passed without an
12+
/// argument. If `NOARG_ALLOWED` is set to `false` then `arg` is guaranteed
13+
/// to always be `Some(_)`.
14+
fn try_from_param_arg(arg: Option<&[u8]>) -> Option<Self>;
815

916
/// # Safety
1017
///
11-
/// `val` must point to a valid null-terminated string. The `arg` field of
12-
/// `param` must be an instance of `Self`.
18+
/// If `val` is non-null then it must point to a valid null-terminated
19+
/// string. The `arg` field of `param` must be an instance of `Self`.
1320
unsafe extern "C" fn set_param(val: *const crate::c_types::c_char, param: *const crate::bindings::kernel_param) -> crate::c_types::c_int {
14-
let arg = crate::c_types::c_string_bytes(val);
21+
let arg = if val.is_null() { None } else { Some(crate::c_types::c_string_bytes(val)) };
1522
match Self::try_from_param_arg(arg) {
1623
Some(new_value) => {
1724
let old_value = (*param).__bindgen_anon_1.arg as *mut Self;
@@ -107,24 +114,46 @@ impl_parse_int!(u64);
107114
impl_parse_int!(isize);
108115
impl_parse_int!(usize);
109116

110-
macro_rules! make_param_ops {
111-
($ops:ident, $ty:ident) => {
117+
macro_rules! impl_module_param {
118+
($ty:ident) => {
112119
impl ModuleParam for $ty {
113-
fn try_from_param_arg(arg: &[u8]) -> Option<Self> {
114-
let utf8 = core::str::from_utf8(arg).ok()?;
120+
const NOARG_ALLOWED: bool = false;
121+
122+
fn try_from_param_arg(arg: Option<&[u8]>) -> Option<Self> {
123+
let bytes = arg?;
124+
let utf8 = core::str::from_utf8(bytes).ok()?;
115125
<$ty as crate::module_param::ParseInt>::from_str(utf8)
116126
}
117127
}
128+
}
129+
}
118130

131+
macro_rules! make_param_ops {
132+
($ops:ident, $ty:ident) => {
119133
pub static $ops: crate::bindings::kernel_param_ops = crate::bindings::kernel_param_ops {
120-
flags: 0,
134+
flags: if <$ty as crate::module_param::ModuleParam>::NOARG_ALLOWED {
135+
crate::bindings::KERNEL_PARAM_OPS_FL_NOARG
136+
} else {
137+
0
138+
},
121139
set: Some(<$ty as crate::module_param::ModuleParam>::set_param),
122140
get: Some(<$ty as crate::module_param::ModuleParam>::get_param),
123141
free: Some(<$ty as crate::module_param::ModuleParam>::free),
124142
};
125143
}
126144
}
127145

146+
impl_module_param!(i8);
147+
impl_module_param!(u8);
148+
impl_module_param!(i16);
149+
impl_module_param!(u16);
150+
impl_module_param!(i32);
151+
impl_module_param!(u32);
152+
impl_module_param!(i64);
153+
impl_module_param!(u64);
154+
impl_module_param!(isize);
155+
impl_module_param!(usize);
156+
128157
make_param_ops!(PARAM_OPS_I8, i8);
129158
make_param_ops!(PARAM_OPS_U8, u8);
130159
make_param_ops!(PARAM_OPS_I16, i16);
@@ -135,3 +164,18 @@ make_param_ops!(PARAM_OPS_I64, i64);
135164
make_param_ops!(PARAM_OPS_U64, u64);
136165
make_param_ops!(PARAM_OPS_ISIZE, isize);
137166
make_param_ops!(PARAM_OPS_USIZE, usize);
167+
168+
impl ModuleParam for bool {
169+
const NOARG_ALLOWED: bool = true;
170+
171+
fn try_from_param_arg(arg: Option<&[u8]>) -> Option<Self> {
172+
match arg {
173+
None => Some(true),
174+
Some(b"y") | Some(b"Y") | Some(b"1") | Some(b"true") => Some(true),
175+
Some(b"n") | Some(b"N") | Some(b"0") | Some(b"false") => Some(false),
176+
_ => None,
177+
}
178+
}
179+
}
180+
181+
make_param_ops!(PARAM_OPS_BOOL, bool);

rust/module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ pub fn module(ts: TokenStream) -> TokenStream {
282282
// TODO: more primitive types
283283
// TODO: other kinds: arrays, unsafes, etc.
284284
let (param_kernel_type, ops) = match param_type.as_ref() {
285-
"bool" => ("bool", "kernel::bindings::param_ops_bool"),
285+
"bool" => ("bool", "kernel::module_param::PARAM_OPS_BOOL"),
286286
"i8" => ("i8", "kernel::module_param::PARAM_OPS_I8"),
287287
"u8" => ("u8", "kernel::module_param::PARAM_OPS_U8"),
288288
"i16" => ("i16", "kernel::module_param::PARAM_OPS_I16"),

0 commit comments

Comments
 (0)