Skip to content

Commit ab0b642

Browse files
committed
Allow miscdev::Registration to carry some context with it.
1 parent 7b7725e commit ab0b642

File tree

2 files changed

+18
-18
lines changed

2 files changed

+18
-18
lines changed

drivers/char/rust_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl KernelModule for RustExample {
150150

151151
Ok(RustExample {
152152
message: "on the heap!".to_owned(),
153-
_dev: miscdev::Registration::new_pinned::<RustFile>(cstr!("rust_miscdev"), None)?,
153+
_dev: miscdev::Registration::new_pinned::<RustFile>(cstr!("rust_miscdev"), None, ())?,
154154
_chrdev: chrdev_reg,
155155
})
156156
}

rust/kernel/miscdev.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,46 @@ use core::marker::PhantomPinned;
1414
use core::pin::Pin;
1515

1616
/// A registration of a miscellaneous device.
17-
pub struct Registration {
17+
pub struct Registration<T: Sync = ()> {
1818
registered: bool,
1919
mdev: bindings::miscdevice,
2020
_pin: PhantomPinned,
21+
22+
/// Context initialised on construction.
23+
pub context: T,
2124
}
2225

23-
impl Registration {
26+
impl<T: Sync> Registration<T> {
2427
/// Creates a new [`Registration`] but does not register it yet.
2528
///
2629
/// It is allowed to move.
27-
pub fn new() -> Self {
30+
pub fn new(context: T) -> Self {
2831
Self {
2932
registered: false,
3033
mdev: bindings::miscdevice::default(),
3134
_pin: PhantomPinned,
35+
context,
3236
}
3337
}
3438

3539
/// Registers a miscellaneous device.
3640
///
3741
/// Returns a pinned heap-allocated representation of the registration.
38-
pub fn new_pinned<T: FileOperations>(
42+
pub fn new_pinned<F: FileOperations>(
3943
name: CStr<'static>,
4044
minor: Option<i32>,
45+
state: T,
4146
) -> KernelResult<Pin<Box<Self>>> {
42-
let mut r = Pin::from(Box::try_new(Self::new())?);
43-
r.as_mut().register::<T>(name, minor)?;
47+
let mut r = Pin::from(Box::try_new(Self::new(state))?);
48+
r.as_mut().register::<F>(name, minor)?;
4449
Ok(r)
4550
}
4651

4752
/// Registers a miscellaneous device with the rest of the kernel.
4853
///
4954
/// It must be pinned because the memory block that represents the registration is
5055
/// self-referential. If a minor is not given, the kernel allocates a new one if possible.
51-
pub fn register<T: FileOperations>(
56+
pub fn register<F: FileOperations>(
5257
self: Pin<&mut Self>,
5358
name: CStr<'static>,
5459
minor: Option<i32>,
@@ -60,7 +65,7 @@ impl Registration {
6065
return Err(Error::EINVAL);
6166
}
6267

63-
this.mdev.fops = FileOperationsVtable::<T>::build();
68+
this.mdev.fops = FileOperationsVtable::<F>::build();
6469
this.mdev.name = name.as_ptr() as *const c_types::c_char;
6570
this.mdev.minor = minor.unwrap_or(bindings::MISC_DYNAMIC_MINOR as i32);
6671

@@ -73,17 +78,12 @@ impl Registration {
7378
}
7479
}
7580

76-
impl Default for Registration {
77-
fn default() -> Self {
78-
Self::new()
79-
}
80-
}
81-
8281
// 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.
84-
unsafe impl Sync for Registration {}
82+
// is safe to pass `&Registration` to multiple threads because it offers no interior mutability,
83+
// except maybe through [`Registration::context`], but it is itself [`Sync`].
84+
unsafe impl<T: Sync> Sync for Registration<T> {}
8585

86-
impl Drop for Registration {
86+
impl<T: Sync> Drop for Registration<T> {
8787
/// Removes the registration from the kernel if it has completed successfully before.
8888
fn drop(&mut self) {
8989
if self.registered {

0 commit comments

Comments
 (0)