rust/kernel/driver.rs
Source file repositories/reference/linux-study-clean/rust/kernel/driver.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/driver.rs- Extension
.rs- Size
- 17443 bytes
- Lines
- 442
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
struct DriverModulefunction callbacks_attachfunction drop
Annotated Snippet
/// This trait describes the layout of a specific driver structure, such as `struct pci_driver` or
/// `struct platform_driver`.
///
/// # Safety
///
/// Implementors must guarantee that:
/// - `DriverType` is `repr(C)`,
/// - `DriverData` is the type of the driver's device private data.
/// - `DriverType` embeds a valid `struct device_driver` at byte offset `DEVICE_DRIVER_OFFSET`.
pub unsafe trait DriverLayout {
/// The specific driver type embedding a `struct device_driver`.
type DriverType: Default;
/// The type of the driver's bus device private data.
type DriverData<'bound>;
/// Byte offset of the embedded `struct device_driver` within `DriverType`.
///
/// This must correspond exactly to the location of the embedded `struct device_driver` field.
const DEVICE_DRIVER_OFFSET: usize;
}
/// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform,
/// Amba, etc.) to provide the corresponding subsystem specific implementation to register /
/// unregister a driver of the particular type (`DriverType`).
///
/// For instance, the PCI subsystem would set `DriverType` to `bindings::pci_driver` and call
/// `bindings::__pci_register_driver` from `RegistrationOps::register` and
/// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`.
///
/// # Safety
///
/// A call to [`RegistrationOps::unregister`] for a given instance of `DriverType` is only valid if
/// a preceding call to [`RegistrationOps::register`] has been successful.
pub unsafe trait RegistrationOps: DriverLayout {
/// Registers a driver.
///
/// # Safety
///
/// On success, `reg` must remain pinned and valid until the matching call to
/// [`RegistrationOps::unregister`].
unsafe fn register(
reg: &Opaque<Self::DriverType>,
name: &'static CStr,
module: &'static ThisModule,
) -> Result;
/// Unregisters a driver previously registered with [`RegistrationOps::register`].
///
/// # Safety
///
/// Must only be called after a preceding successful call to [`RegistrationOps::register`] for
/// the same `reg`.
unsafe fn unregister(reg: &Opaque<Self::DriverType>);
}
/// A [`Registration`] is a generic type that represents the registration of some driver type (e.g.
/// `bindings::pci_driver`). Therefore a [`Registration`] must be initialized with a type that
/// implements the [`RegistrationOps`] trait, such that the generic `T::register` and
/// `T::unregister` calls result in the subsystem specific registration calls.
///
///Once the `Registration` structure is dropped, the driver is unregistered.
#[pin_data(PinnedDrop)]
pub struct Registration<T: RegistrationOps> {
#[pin]
reg: Opaque<T::DriverType>,
}
// SAFETY: `Registration` has no fields or methods accessible via `&Registration`, so it is safe to
// share references to it with multiple threads as nothing can be done.
unsafe impl<T: RegistrationOps> Sync for Registration<T> {}
// SAFETY: Both registration and unregistration are implemented in C and safe to be performed from
// any thread, so `Registration` is `Send`.
unsafe impl<T: RegistrationOps> Send for Registration<T> {}
impl<T: RegistrationOps> Registration<T> {
extern "C" fn post_unbind_callback(dev: *mut bindings::device) {
// SAFETY: The driver core only ever calls the post unbind callback with a valid pointer to
// a `struct device`.
//
// INVARIANT: `dev` is valid for the duration of the `post_unbind_callback()`.
let dev = unsafe { &*dev.cast::<device::Device<device::CoreInternal<'_>>>() };
// `remove()` has been completed at this point; devres resources are still valid and will
// be released after the driver's bus device private data is dropped.
//
// SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the
// driver's bus device private data type.
drop(unsafe { dev.drvdata_obtain::<T::DriverData<'_>>() });
Annotation
- Detected declarations: `struct DriverModule`, `function callbacks_attach`, `function drop`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: pattern implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.