88
99use crate :: bindings;
1010use crate :: error:: { Error , Result } ;
11- use crate :: file_operations:: { FileOpenAdapter , FileOpener , FileOperationsVtable } ;
11+ use crate :: file_operations:: { FileOpenAdapter , FileOperations , FileOperationsVtable } ;
1212use crate :: { str:: CStr , KernelModule , ThisModule } ;
1313use alloc:: boxed:: Box ;
14- use core:: marker:: { PhantomData , PhantomPinned } ;
14+ use core:: marker:: PhantomPinned ;
1515use core:: { mem:: MaybeUninit , pin:: Pin } ;
1616
1717/// A registration of a miscellaneous device.
1818///
1919/// # Invariants
2020///
2121/// `Context` is always initialised when `registered` is `true`, and not initialised otherwise.
22- pub struct Registration < T : Sync = ( ) > {
22+ pub struct Registration < T : FileOperations > {
2323 registered : bool ,
2424 mdev : bindings:: miscdevice ,
2525 _pin : PhantomPinned ,
2626
2727 /// Context initialised on construction and made available to all file instances on
28- /// [`FileOpener ::open`].
29- open_data : MaybeUninit < T > ,
28+ /// [`FileOperations ::open`].
29+ open_data : MaybeUninit < T :: OpenData > ,
3030}
3131
32- impl < T : Sync > Registration < T > {
32+ impl < T : FileOperations > Registration < T > {
3333 /// Creates a new [`Registration`] but does not register it yet.
3434 ///
3535 /// It is allowed to move.
@@ -46,25 +46,25 @@ impl<T: Sync> Registration<T> {
4646 /// Registers a miscellaneous device.
4747 ///
4848 /// Returns a pinned heap-allocated representation of the registration.
49- pub fn new_pinned < F : FileOpener < T > > (
49+ pub fn new_pinned (
5050 name : & ' static CStr ,
5151 minor : Option < i32 > ,
52- open_data : T ,
52+ open_data : T :: OpenData ,
5353 ) -> Result < Pin < Box < Self > > > {
5454 let mut r = Pin :: from ( Box :: try_new ( Self :: new ( ) ) ?) ;
55- r. as_mut ( ) . register :: < F > ( name, minor, open_data) ?;
55+ r. as_mut ( ) . register ( name, minor, open_data) ?;
5656 Ok ( r)
5757 }
5858
5959 /// Registers a miscellaneous device with the rest of the kernel.
6060 ///
6161 /// It must be pinned because the memory block that represents the registration is
6262 /// self-referential. If a minor is not given, the kernel allocates a new one if possible.
63- pub fn register < F : FileOpener < T > > (
63+ pub fn register (
6464 self : Pin < & mut Self > ,
6565 name : & ' static CStr ,
6666 minor : Option < i32 > ,
67- open_data : T ,
67+ open_data : T :: OpenData ,
6868 ) -> Result {
6969 // SAFETY: We must ensure that we never move out of `this`.
7070 let this = unsafe { self . get_unchecked_mut ( ) } ;
@@ -74,7 +74,7 @@ impl<T: Sync> Registration<T> {
7474 }
7575
7676 // SAFETY: The adapter is compatible with `misc_register`.
77- this. mdev . fops = unsafe { FileOperationsVtable :: < Self , F > :: build ( ) } ;
77+ this. mdev . fops = unsafe { FileOperationsVtable :: < Self , T > :: build ( ) } ;
7878 this. mdev . name = name. as_char_ptr ( ) ;
7979 this. mdev . minor = minor. unwrap_or ( bindings:: MISC_DYNAMIC_MINOR as i32 ) ;
8080
@@ -98,16 +98,17 @@ impl<T: Sync> Registration<T> {
9898 }
9999}
100100
101- impl < T : Sync > Default for Registration < T > {
101+ impl < T : FileOperations > Default for Registration < T > {
102102 fn default ( ) -> Self {
103103 Self :: new ( )
104104 }
105105}
106106
107- impl < T : Sync > FileOpenAdapter for Registration < T > {
108- type Arg = T ;
109-
110- unsafe fn convert ( _inode : * mut bindings:: inode , file : * mut bindings:: file ) -> * const Self :: Arg {
107+ impl < T : FileOperations > FileOpenAdapter < T :: OpenData > for Registration < T > {
108+ unsafe fn convert (
109+ _inode : * mut bindings:: inode ,
110+ file : * mut bindings:: file ,
111+ ) -> * const T :: OpenData {
111112 // SAFETY: the caller must guarantee that `file` is valid.
112113 let reg = crate :: container_of!( unsafe { ( * file) . private_data } , Self , mdev) ;
113114
@@ -120,14 +121,13 @@ impl<T: Sync> FileOpenAdapter for Registration<T> {
120121
121122// SAFETY: The only method is `register()`, which requires a (pinned) mutable `Registration`, so it
122123// is safe to pass `&Registration` to multiple threads because it offers no interior mutability.
123- unsafe impl < T : Sync > Sync for Registration < T > { }
124+ unsafe impl < T : FileOperations > Sync for Registration < T > { }
124125
125126// SAFETY: All functions work from any thread. So as long as the `Registration::open_data` is
126- // `Send`, so is `Registration<T>`. `T` needs to be `Sync` because it's a requirement of
127- // `Registration<T>`.
128- unsafe impl < T : Send + Sync > Send for Registration < T > { }
127+ // `Send`, so is `Registration<T>`.
128+ unsafe impl < T : FileOperations > Send for Registration < T > where T :: OpenData : Send { }
129129
130- impl < T : Sync > Drop for Registration < T > {
130+ impl < T : FileOperations > Drop for Registration < T > {
131131 /// Removes the registration from the kernel if it has completed successfully before.
132132 fn drop ( & mut self ) {
133133 if self . registered {
@@ -142,17 +142,15 @@ impl<T: Sync> Drop for Registration<T> {
142142 }
143143}
144144
145- /// Kernel module that exposes a single miscdev device implemented by `F`.
146- pub struct Module < F : FileOpener < ( ) > > {
147- _dev : Pin < Box < Registration > > ,
148- _p : PhantomData < F > ,
145+ /// Kernel module that exposes a single miscdev device implemented by `T`.
146+ pub struct Module < T : FileOperations < OpenData = ( ) > > {
147+ _dev : Pin < Box < Registration < T > > > ,
149148}
150149
151- impl < F : FileOpener < ( ) > > KernelModule for Module < F > {
150+ impl < T : FileOperations < OpenData = ( ) > > KernelModule for Module < T > {
152151 fn init ( name : & ' static CStr , _module : & ' static ThisModule ) -> Result < Self > {
153152 Ok ( Self {
154- _p : PhantomData ,
155- _dev : Registration :: new_pinned :: < F > ( name, None , ( ) ) ?,
153+ _dev : Registration :: new_pinned ( name, None , ( ) ) ?,
156154 } )
157155 }
158156}
0 commit comments