Skip to content

Commit a553727

Browse files
authored
Merge pull request #162 from wedsonaf/miscdevT
Allow `miscdev::Registration` to carry some context with it.
2 parents 570300f + fc8cc48 commit a553727

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

drivers/char/rust_example.rs

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

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

rust/kernel/miscdev.rs

Lines changed: 22 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+
context: 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(context))?);
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,17 @@ 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> {}
85+
86+
// SAFETY: All functions work from any thread. So as long as the `Registration::context` is
87+
// `Send`, so is `Registration<T>`. `T` needs to be `Sync` because it's a requirement of
88+
// `Registration<T>`.
89+
unsafe impl<T: Send + Sync> Send for Registration<T> {}
8590

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

0 commit comments

Comments
 (0)