1*0752a2e9SAlvin Sun // SPDX-License-Identifier: GPL-2.0 2*0752a2e9SAlvin Sun 3*0752a2e9SAlvin Sun //! Module-related types and helpers. 4*0752a2e9SAlvin Sun 5*0752a2e9SAlvin Sun /// The entrypoint to implementing a kernel module. 6*0752a2e9SAlvin Sun /// 7*0752a2e9SAlvin Sun /// For any teardown or cleanup operations, your type may implement [`Drop`]. 8*0752a2e9SAlvin Sun pub trait Module: Sized + Sync + Send { 9*0752a2e9SAlvin Sun /// Called at module initialization time. 10*0752a2e9SAlvin Sun /// 11*0752a2e9SAlvin Sun /// Use this method to perform whatever setup or registration your module 12*0752a2e9SAlvin Sun /// should do. 13*0752a2e9SAlvin Sun /// 14*0752a2e9SAlvin Sun /// Equivalent to the `module_init` macro in the C API. 15*0752a2e9SAlvin Sun fn init(module: &'static ThisModule) -> crate::error::Result<Self>; 16*0752a2e9SAlvin Sun } 17*0752a2e9SAlvin Sun 18*0752a2e9SAlvin Sun /// A module that is pinned and initialised in-place. 19*0752a2e9SAlvin Sun pub trait InPlaceModule: Sync + Send { 20*0752a2e9SAlvin Sun /// Creates an initialiser for the module. 21*0752a2e9SAlvin Sun /// 22*0752a2e9SAlvin Sun /// It is called when the module is loaded. 23*0752a2e9SAlvin Sun fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error>; 24*0752a2e9SAlvin Sun } 25*0752a2e9SAlvin Sun 26*0752a2e9SAlvin Sun impl<T: Module> InPlaceModule for T { 27*0752a2e9SAlvin Sun fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error> { 28*0752a2e9SAlvin Sun let initer = move |slot: *mut Self| { 29*0752a2e9SAlvin Sun let m = <Self as Module>::init(module)?; 30*0752a2e9SAlvin Sun 31*0752a2e9SAlvin Sun // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`. 32*0752a2e9SAlvin Sun unsafe { slot.write(m) }; 33*0752a2e9SAlvin Sun Ok(()) 34*0752a2e9SAlvin Sun }; 35*0752a2e9SAlvin Sun 36*0752a2e9SAlvin Sun // SAFETY: On success, `initer` always fully initialises an instance of `Self`. 37*0752a2e9SAlvin Sun unsafe { pin_init::pin_init_from_closure(initer) } 38*0752a2e9SAlvin Sun } 39*0752a2e9SAlvin Sun } 40*0752a2e9SAlvin Sun 41*0752a2e9SAlvin Sun /// Metadata attached to a [`Module`] or [`InPlaceModule`]. 42*0752a2e9SAlvin Sun pub trait ModuleMetadata { 43*0752a2e9SAlvin Sun /// The name of the module as specified in the `module!` macro. 44*0752a2e9SAlvin Sun const NAME: &'static crate::str::CStr; 45*0752a2e9SAlvin Sun } 46*0752a2e9SAlvin Sun 47*0752a2e9SAlvin Sun /// Equivalent to `THIS_MODULE` in the C API. 48*0752a2e9SAlvin Sun /// 49*0752a2e9SAlvin Sun /// C header: [`include/linux/init.h`](srctree/include/linux/init.h) 50*0752a2e9SAlvin Sun pub struct ThisModule(*mut crate::bindings::module); 51*0752a2e9SAlvin Sun 52*0752a2e9SAlvin Sun // SAFETY: `THIS_MODULE` may be used from all threads within a module. 53*0752a2e9SAlvin Sun unsafe impl Sync for ThisModule {} 54*0752a2e9SAlvin Sun 55*0752a2e9SAlvin Sun impl ThisModule { 56*0752a2e9SAlvin Sun /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer. 57*0752a2e9SAlvin Sun /// 58*0752a2e9SAlvin Sun /// # Safety 59*0752a2e9SAlvin Sun /// 60*0752a2e9SAlvin Sun /// The pointer must be equal to the right `THIS_MODULE`. 61*0752a2e9SAlvin Sun pub const unsafe fn from_ptr(ptr: *mut crate::bindings::module) -> ThisModule { 62*0752a2e9SAlvin Sun ThisModule(ptr) 63*0752a2e9SAlvin Sun } 64*0752a2e9SAlvin Sun 65*0752a2e9SAlvin Sun /// Access the raw pointer for this module. 66*0752a2e9SAlvin Sun /// 67*0752a2e9SAlvin Sun /// It is up to the user to use it correctly. 68*0752a2e9SAlvin Sun pub const fn as_ptr(&self) -> *mut crate::bindings::module { 69*0752a2e9SAlvin Sun self.0 70*0752a2e9SAlvin Sun } 71*0752a2e9SAlvin Sun } 72