@@ -4,14 +4,21 @@ use core::fmt::Write;
4
4
/// Note that displaying the type in `sysfs` will fail if `to_string` returns
5
5
/// more than `kernel::PAGE_SIZE` bytes (including an additional null terminator).
6
6
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 > ;
8
15
9
16
/// # Safety
10
17
///
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`.
13
20
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) ) } ;
15
22
match Self :: try_from_param_arg ( arg) {
16
23
Some ( new_value) => {
17
24
let old_value = ( * param) . __bindgen_anon_1 . arg as * mut Self ;
@@ -107,24 +114,46 @@ impl_parse_int!(u64);
107
114
impl_parse_int ! ( isize ) ;
108
115
impl_parse_int ! ( usize ) ;
109
116
110
- macro_rules! make_param_ops {
111
- ( $ops : ident , $ ty: ident) => {
117
+ macro_rules! impl_module_param {
118
+ ( $ty: ident) => {
112
119
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( ) ?;
115
125
<$ty as crate :: module_param:: ParseInt >:: from_str( utf8)
116
126
}
117
127
}
128
+ }
129
+ }
118
130
131
+ macro_rules! make_param_ops {
132
+ ( $ops: ident, $ty: ident) => {
119
133
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
+ } ,
121
139
set: Some ( <$ty as crate :: module_param:: ModuleParam >:: set_param) ,
122
140
get: Some ( <$ty as crate :: module_param:: ModuleParam >:: get_param) ,
123
141
free: Some ( <$ty as crate :: module_param:: ModuleParam >:: free) ,
124
142
} ;
125
143
}
126
144
}
127
145
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
+
128
157
make_param_ops ! ( PARAM_OPS_I8 , i8 ) ;
129
158
make_param_ops ! ( PARAM_OPS_U8 , u8 ) ;
130
159
make_param_ops ! ( PARAM_OPS_I16 , i16 ) ;
@@ -135,3 +164,18 @@ make_param_ops!(PARAM_OPS_I64, i64);
135
164
make_param_ops ! ( PARAM_OPS_U64 , u64 ) ;
136
165
make_param_ops ! ( PARAM_OPS_ISIZE , isize ) ;
137
166
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 ) ;
0 commit comments