11// SPDX-License-Identifier: GPL-2.0
22
3+ //! Character devices.
4+ //!
5+ //! Also called "char devices", `chrdev`, `cdev`.
6+ //!
7+ //! C header: [`include/linux/cdev.h`](../../../../include/linux/cdev.h)
8+ //!
9+ //! Reference: <https://www.kernel.org/doc/html/latest/core-api/kernel-api.html#char-devices>
10+
311use alloc:: boxed:: Box ;
412use core:: convert:: TryInto ;
513use core:: marker:: PhantomPinned ;
@@ -19,8 +27,9 @@ struct RegistrationInner<const N: usize> {
1927 _pin : PhantomPinned ,
2028}
2129
22- /// chrdev registration. May contain up to a fixed number (`N`) of devices.
23- /// Must be pinned.
30+ /// Character device registration.
31+ ///
32+ /// May contain up to a fixed number (`N`) of devices. Must be pinned.
2433pub struct Registration < const N : usize > {
2534 name : CStr < ' static > ,
2635 minors_start : u16 ,
@@ -29,6 +38,15 @@ pub struct Registration<const N: usize> {
2938}
3039
3140impl < const N : usize > Registration < { N } > {
41+ /// Creates a [`Registration`] object for a character device.
42+ ///
43+ /// This does *not* register the device: see [`Self::register()`].
44+ ///
45+ /// This associated function is intended to be used when you need to avoid
46+ /// a memory allocation, e.g. when the [`Registration`] is a member of
47+ /// a bigger structure inside your [`crate::KernelModule`] instance. If you
48+ /// are going to pin the registration right away, call
49+ /// [`Self::new_pinned()`] instead.
3250 pub fn new (
3351 name : CStr < ' static > ,
3452 minors_start : u16 ,
@@ -42,6 +60,9 @@ impl<const N: usize> Registration<{ N }> {
4260 }
4361 }
4462
63+ /// Creates a pinned [`Registration`] object for a character device.
64+ ///
65+ /// This does *not* register the device: see [`Self::register()`].
4566 pub fn new_pinned (
4667 name : CStr < ' static > ,
4768 minors_start : u16 ,
@@ -53,15 +74,17 @@ impl<const N: usize> Registration<{ N }> {
5374 this_module,
5475 ) ) ?) )
5576 }
56- /// Register a character device with this range. Call this once per device
57- /// type (up to `N` times).
77+
78+ /// Registers a character device.
79+ ///
80+ /// You may call this once per device type, up to `N` times.
5881 pub fn register < T : file_operations:: FileOperations > ( self : Pin < & mut Self > ) -> KernelResult < ( ) > {
59- // SAFETY: we must ensure that we never move out of `this`.
82+ // SAFETY: We must ensure that we never move out of `this`.
6083 let this = unsafe { self . get_unchecked_mut ( ) } ;
6184 if this. inner . is_none ( ) {
6285 let mut dev: bindings:: dev_t = 0 ;
63- // SAFETY: Calling unsafe function. `this.name` has 'static
64- // lifetime
86+ // SAFETY: Calling unsafe function. `this.name` has ` 'static`
87+ // lifetime.
6588 let res = unsafe {
6689 bindings:: alloc_chrdev_region (
6790 & mut dev,
@@ -86,7 +109,8 @@ impl<const N: usize> Registration<{ N }> {
86109 return Err ( Error :: EINVAL ) ;
87110 }
88111 let cdev = inner. cdevs [ inner. used ] . as_mut_ptr ( ) ;
89- // SAFETY: calling unsafe functions and manipulating MaybeUninit ptr.
112+ // SAFETY: Calling unsafe functions and manipulating `MaybeUninit`
113+ // pointer.
90114 unsafe {
91115 bindings:: cdev_init ( cdev, & file_operations:: FileOperationsVtable :: < T > :: VTABLE ) ;
92116 ( * cdev) . owner = this. this_module . 0 ;
@@ -100,14 +124,14 @@ impl<const N: usize> Registration<{ N }> {
100124 }
101125}
102126
103- // SAFETY: `Registration` doesn't expose any of its state across threads (it's
104- // fine for multiple threads to have a shared reference to it).
127+ // SAFETY: `Registration` does not expose any of its state across threads
128+ // (it is fine for multiple threads to have a shared reference to it).
105129unsafe impl < const N : usize > Sync for Registration < { N } > { }
106130
107131impl < const N : usize > Drop for Registration < { N } > {
108132 fn drop ( & mut self ) {
109133 if let Some ( inner) = self . inner . as_mut ( ) {
110- // SAFETY: calling unsafe functions, `0..inner.used` of
134+ // SAFETY: Calling unsafe functions, `0..inner.used` of
111135 // `inner.cdevs` are initialized in `Registration::register`.
112136 unsafe {
113137 for i in 0 ..inner. used {
0 commit comments