@@ -15,7 +15,8 @@ use core::pin::Pin;
15
15
16
16
/// A registration of a miscellaneous device.
17
17
pub struct Registration {
18
- mdev : Option < bindings:: miscdevice > ,
18
+ registered : bool ,
19
+ mdev : bindings:: miscdevice ,
19
20
_pin : PhantomPinned ,
20
21
}
21
22
@@ -25,7 +26,8 @@ impl Registration {
25
26
/// It is allowed to move.
26
27
pub fn new ( ) -> Self {
27
28
Self {
28
- mdev : None ,
29
+ registered : false ,
30
+ mdev : bindings:: miscdevice:: default ( ) ,
29
31
_pin : PhantomPinned ,
30
32
}
31
33
}
@@ -44,31 +46,29 @@ impl Registration {
44
46
45
47
/// Registers a miscellaneous device with the rest of the kernel.
46
48
///
47
- /// It must be pinned because the memory block that represents the
48
- /// registration is self-referential. If a minor is not given, the kernel
49
- /// allocates a new one if possible.
49
+ /// It must be pinned because the memory block that represents the registration is
50
+ /// self-referential. If a minor is not given, the kernel allocates a new one if possible.
50
51
pub fn register < T : FileOperations > (
51
52
self : Pin < & mut Self > ,
52
53
name : CStr < ' static > ,
53
54
minor : Option < i32 > ,
54
55
) -> KernelResult {
55
56
// SAFETY: We must ensure that we never move out of `this`.
56
57
let this = unsafe { self . get_unchecked_mut ( ) } ;
57
- if this. mdev . is_some ( ) {
58
+ if this. registered {
58
59
// Already registered.
59
60
return Err ( Error :: EINVAL ) ;
60
61
}
61
62
62
- this. mdev = Some ( bindings:: miscdevice:: default ( ) ) ;
63
- let dev = this. mdev . as_mut ( ) . unwrap ( ) ;
64
- dev. fops = FileOperationsVtable :: < T > :: build ( ) ;
65
- dev. name = name. as_ptr ( ) as * const c_types:: c_char ;
66
- dev. minor = minor. unwrap_or ( bindings:: MISC_DYNAMIC_MINOR as i32 ) ;
67
- let ret = unsafe { bindings:: misc_register ( dev) } ;
63
+ this. mdev . fops = FileOperationsVtable :: < T > :: build ( ) ;
64
+ this. mdev . name = name. as_ptr ( ) as * const c_types:: c_char ;
65
+ this. mdev . minor = minor. unwrap_or ( bindings:: MISC_DYNAMIC_MINOR as i32 ) ;
66
+
67
+ let ret = unsafe { bindings:: misc_register ( & mut this. mdev ) } ;
68
68
if ret < 0 {
69
- this. mdev = None ;
70
69
return Err ( Error :: from_kernel_errno ( ret) ) ;
71
70
}
71
+ this. registered = true ;
72
72
Ok ( ( ) )
73
73
}
74
74
}
@@ -79,19 +79,15 @@ impl Default for Registration {
79
79
}
80
80
}
81
81
82
- // SAFETY: The only method is `register()`, which requires a (pinned) mutable
83
- // `Registration`, so it is safe to pass `&Registration` to multiple threads
84
- // because it offers no interior mutability.
82
+ // SAFETY: The only method is `register()`, which requires a (pinned) mutable `Registration`, so it
83
+ // is safe to pass `&Registration` to multiple threads because it offers no interior mutability.
85
84
unsafe impl Sync for Registration { }
86
85
87
86
impl Drop for Registration {
88
- /// Removes the registration from the kernel if it has completed
89
- /// successfully before.
87
+ /// Removes the registration from the kernel if it has completed successfully before.
90
88
fn drop ( & mut self ) {
91
- if let Some ( ref mut dev) = self . mdev {
92
- unsafe {
93
- bindings:: misc_deregister ( dev) ;
94
- }
89
+ if self . registered {
90
+ unsafe { bindings:: misc_deregister ( & mut self . mdev ) }
95
91
}
96
92
}
97
93
}
0 commit comments