mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Driver core fixes for 6.16-rc3
- Fix swapped handling of lru_gen and lru_gen_full debugfs files in vmscan. - Fix debugfs mount options (uid, gid, mode) being silently ignored. - Fix leak of devres action in the unwind path of Devres::new(). - Documentation - Expand and fix documentation of (outdated) Device, DeviceContext and generic driver infrastructure. - Fix C header link of faux device abstractions. - Clarify expected interaction with the security team. - Smooth text flow in the security bug reporting process documentation. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQS2q/xV6QjXAdC7k+1FlHeO1qrKLgUCaKmYLgAKCRBFlHeO1qrK LuUiAQDMA7wZCdzvU8kZazpVpiN5t4Y/EeCztbZJlTG1b0F66QEAgKfgBbdKdgvu LNSXY0Mo6/t6RbFbW5+wR4R+sGn6PwQ= =wBy0 -----END PGP SIGNATURE----- Merge tag 'driver-core-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core Pull driver core fixes from Danilo Krummrich: - Fix swapped handling of lru_gen and lru_gen_full debugfs files in vmscan - Fix debugfs mount options (uid, gid, mode) being silently ignored - Fix leak of devres action in the unwind path of Devres::new() - Documentation: - Expand and fix documentation of (outdated) Device, DeviceContext and generic driver infrastructure - Fix C header link of faux device abstractions - Clarify expected interaction with the security team - Smooth text flow in the security bug reporting process documentation * tag 'driver-core-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: Documentation: smooth the text flow in the security bug reporting process Documentation: clarify the expected collaboration with security bugs reporters debugfs: fix mount options not being applied rust: devres: fix leaking call to devm_add_action() rust: faux: fix C header link driver: rust: expand documentation for driver infrastructure device: rust: expand documentation for Device device: rust: expand documentation for DeviceContext mm/vmscan: fix inverted polarity in lru_gen_seq_show()
This commit is contained in:
commit
52025b8fc9
@ -8,8 +8,22 @@ like to know when a security bug is found so that it can be fixed and
|
||||
disclosed as quickly as possible. Please report security bugs to the
|
||||
Linux kernel security team.
|
||||
|
||||
Contact
|
||||
-------
|
||||
The security team and maintainers almost always require additional
|
||||
information beyond what was initially provided in a report and rely on
|
||||
active and efficient collaboration with the reporter to perform further
|
||||
testing (e.g., verifying versions, configuration options, mitigations, or
|
||||
patches). Before contacting the security team, the reporter must ensure
|
||||
they are available to explain their findings, engage in discussions, and
|
||||
run additional tests. Reports where the reporter does not respond promptly
|
||||
or cannot effectively discuss their findings may be abandoned if the
|
||||
communication does not quickly improve.
|
||||
|
||||
As it is with any bug, the more information provided the easier it
|
||||
will be to diagnose and fix. Please review the procedure outlined in
|
||||
'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
|
||||
information is helpful. Any exploit code is very helpful and will not
|
||||
be released without consent from the reporter unless it has already been
|
||||
made public.
|
||||
|
||||
The Linux kernel security team can be contacted by email at
|
||||
<security@kernel.org>. This is a private list of security officers
|
||||
@ -19,13 +33,6 @@ that can speed up the process considerably. It is possible that the
|
||||
security team will bring in extra help from area maintainers to
|
||||
understand and fix the security vulnerability.
|
||||
|
||||
As it is with any bug, the more information provided the easier it
|
||||
will be to diagnose and fix. Please review the procedure outlined in
|
||||
'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
|
||||
information is helpful. Any exploit code is very helpful and will not
|
||||
be released without consent from the reporter unless it has already been
|
||||
made public.
|
||||
|
||||
Please send plain text emails without attachments where possible.
|
||||
It is much harder to have a context-quoted discussion about a complex
|
||||
issue if all the details are hidden away in attachments. Think of it like a
|
||||
|
@ -183,6 +183,9 @@ static int debugfs_reconfigure(struct fs_context *fc)
|
||||
struct debugfs_fs_info *sb_opts = sb->s_fs_info;
|
||||
struct debugfs_fs_info *new_opts = fc->s_fs_info;
|
||||
|
||||
if (!new_opts)
|
||||
return 0;
|
||||
|
||||
sync_filesystem(sb);
|
||||
|
||||
/* structure copy of new mount options to sb */
|
||||
@ -282,10 +285,16 @@ static int debugfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
|
||||
static int debugfs_get_tree(struct fs_context *fc)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!(debugfs_allow & DEBUGFS_ALLOW_API))
|
||||
return -EPERM;
|
||||
|
||||
return get_tree_single(fc, debugfs_fill_super);
|
||||
err = get_tree_single(fc, debugfs_fill_super);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return debugfs_reconfigure(fc);
|
||||
}
|
||||
|
||||
static void debugfs_free_fc(struct fs_context *fc)
|
||||
|
@ -5772,9 +5772,9 @@ static int __init init_lru_gen(void)
|
||||
if (sysfs_create_group(mm_kobj, &lru_gen_attr_group))
|
||||
pr_err("lru_gen: failed to create sysfs group\n");
|
||||
|
||||
debugfs_create_file_aux_num("lru_gen", 0644, NULL, NULL, 1,
|
||||
debugfs_create_file_aux_num("lru_gen", 0644, NULL, NULL, false,
|
||||
&lru_gen_rw_fops);
|
||||
debugfs_create_file_aux_num("lru_gen_full", 0444, NULL, NULL, 0,
|
||||
debugfs_create_file_aux_num("lru_gen_full", 0444, NULL, NULL, true,
|
||||
&lru_gen_ro_fops);
|
||||
|
||||
return 0;
|
||||
|
@ -15,23 +15,130 @@ use crate::c_str;
|
||||
|
||||
pub mod property;
|
||||
|
||||
/// A reference-counted device.
|
||||
/// The core representation of a device in the kernel's driver model.
|
||||
///
|
||||
/// This structure represents the Rust abstraction for a C `struct device`. This implementation
|
||||
/// abstracts the usage of an already existing C `struct device` within Rust code that we get
|
||||
/// passed from the C side.
|
||||
/// This structure represents the Rust abstraction for a C `struct device`. A [`Device`] can either
|
||||
/// exist as temporary reference (see also [`Device::from_raw`]), which is only valid within a
|
||||
/// certain scope or as [`ARef<Device>`], owning a dedicated reference count.
|
||||
///
|
||||
/// An instance of this abstraction can be obtained temporarily or permanent.
|
||||
/// # Device Types
|
||||
///
|
||||
/// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation.
|
||||
/// A permanent instance is always reference-counted and hence not restricted by any lifetime
|
||||
/// boundaries.
|
||||
/// A [`Device`] can represent either a bus device or a class device.
|
||||
///
|
||||
/// For subsystems it is recommended to create a permanent instance to wrap into a subsystem
|
||||
/// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in
|
||||
/// `T::probe()`, such that a driver can store the `ARef<Device>` (equivalent to storing a
|
||||
/// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent
|
||||
/// memory.
|
||||
/// ## Bus Devices
|
||||
///
|
||||
/// A bus device is a [`Device`] that is associated with a physical or virtual bus. Examples of
|
||||
/// buses include PCI, USB, I2C, and SPI. Devices attached to a bus are registered with a specific
|
||||
/// bus type, which facilitates matching devices with appropriate drivers based on IDs or other
|
||||
/// identifying information. Bus devices are visible in sysfs under `/sys/bus/<bus-name>/devices/`.
|
||||
///
|
||||
/// ## Class Devices
|
||||
///
|
||||
/// A class device is a [`Device`] that is associated with a logical category of functionality
|
||||
/// rather than a physical bus. Examples of classes include block devices, network interfaces, sound
|
||||
/// cards, and input devices. Class devices are grouped under a common class and exposed to
|
||||
/// userspace via entries in `/sys/class/<class-name>/`.
|
||||
///
|
||||
/// # Device Context
|
||||
///
|
||||
/// [`Device`] references are generic over a [`DeviceContext`], which represents the type state of
|
||||
/// a [`Device`].
|
||||
///
|
||||
/// As the name indicates, this type state represents the context of the scope the [`Device`]
|
||||
/// reference is valid in. For instance, the [`Bound`] context guarantees that the [`Device`] is
|
||||
/// bound to a driver for the entire duration of the existence of a [`Device<Bound>`] reference.
|
||||
///
|
||||
/// Other [`DeviceContext`] types besides [`Bound`] are [`Normal`], [`Core`] and [`CoreInternal`].
|
||||
///
|
||||
/// Unless selected otherwise [`Device`] defaults to the [`Normal`] [`DeviceContext`], which by
|
||||
/// itself has no additional requirements.
|
||||
///
|
||||
/// It is always up to the caller of [`Device::from_raw`] to select the correct [`DeviceContext`]
|
||||
/// type for the corresponding scope the [`Device`] reference is created in.
|
||||
///
|
||||
/// All [`DeviceContext`] types other than [`Normal`] are intended to be used with
|
||||
/// [bus devices](#bus-devices) only.
|
||||
///
|
||||
/// # Implementing Bus Devices
|
||||
///
|
||||
/// This section provides a guideline to implement bus specific devices, such as [`pci::Device`] or
|
||||
/// [`platform::Device`].
|
||||
///
|
||||
/// A bus specific device should be defined as follows.
|
||||
///
|
||||
/// ```ignore
|
||||
/// #[repr(transparent)]
|
||||
/// pub struct Device<Ctx: device::DeviceContext = device::Normal>(
|
||||
/// Opaque<bindings::bus_device_type>,
|
||||
/// PhantomData<Ctx>,
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// Since devices are reference counted, [`AlwaysRefCounted`] should be implemented for `Device`
|
||||
/// (i.e. `Device<Normal>`). Note that [`AlwaysRefCounted`] must not be implemented for any other
|
||||
/// [`DeviceContext`], since all other device context types are only valid within a certain scope.
|
||||
///
|
||||
/// In order to be able to implement the [`DeviceContext`] dereference hierarchy, bus device
|
||||
/// implementations should call the [`impl_device_context_deref`] macro as shown below.
|
||||
///
|
||||
/// ```ignore
|
||||
/// // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s
|
||||
/// // generic argument.
|
||||
/// kernel::impl_device_context_deref!(unsafe { Device });
|
||||
/// ```
|
||||
///
|
||||
/// In order to convert from a any [`Device<Ctx>`] to [`ARef<Device>`], bus devices can implement
|
||||
/// the following macro call.
|
||||
///
|
||||
/// ```ignore
|
||||
/// kernel::impl_device_context_into_aref!(Device);
|
||||
/// ```
|
||||
///
|
||||
/// Bus devices should also implement the following [`AsRef`] implementation, such that users can
|
||||
/// easily derive a generic [`Device`] reference.
|
||||
///
|
||||
/// ```ignore
|
||||
/// impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
|
||||
/// fn as_ref(&self) -> &device::Device<Ctx> {
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Implementing Class Devices
|
||||
///
|
||||
/// Class device implementations require less infrastructure and depend slightly more on the
|
||||
/// specific subsystem.
|
||||
///
|
||||
/// An example implementation for a class device could look like this.
|
||||
///
|
||||
/// ```ignore
|
||||
/// #[repr(C)]
|
||||
/// pub struct Device<T: class::Driver> {
|
||||
/// dev: Opaque<bindings::class_device_type>,
|
||||
/// data: T::Data,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This class device uses the sub-classing pattern to embed the driver's private data within the
|
||||
/// allocation of the class device. For this to be possible the class device is generic over the
|
||||
/// class specific `Driver` trait implementation.
|
||||
///
|
||||
/// Just like any device, class devices are reference counted and should hence implement
|
||||
/// [`AlwaysRefCounted`] for `Device`.
|
||||
///
|
||||
/// Class devices should also implement the following [`AsRef`] implementation, such that users can
|
||||
/// easily derive a generic [`Device`] reference.
|
||||
///
|
||||
/// ```ignore
|
||||
/// impl<T: class::Driver> AsRef<device::Device> for Device<T> {
|
||||
/// fn as_ref(&self) -> &device::Device {
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// An example for a class device implementation is [`drm::Device`].
|
||||
///
|
||||
/// # Invariants
|
||||
///
|
||||
@ -42,6 +149,12 @@ pub mod property;
|
||||
///
|
||||
/// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be
|
||||
/// dropped from any thread.
|
||||
///
|
||||
/// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted
|
||||
/// [`drm::Device`]: kernel::drm::Device
|
||||
/// [`impl_device_context_deref`]: kernel::impl_device_context_deref
|
||||
/// [`pci::Device`]: kernel::pci::Device
|
||||
/// [`platform::Device`]: kernel::platform::Device
|
||||
#[repr(transparent)]
|
||||
pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>);
|
||||
|
||||
@ -311,28 +424,75 @@ unsafe impl Send for Device {}
|
||||
// synchronization in `struct device`.
|
||||
unsafe impl Sync for Device {}
|
||||
|
||||
/// Marker trait for the context of a bus specific device.
|
||||
/// Marker trait for the context or scope of a bus specific device.
|
||||
///
|
||||
/// Some functions of a bus specific device should only be called from a certain context, i.e. bus
|
||||
/// callbacks, such as `probe()`.
|
||||
/// [`DeviceContext`] is a marker trait for types representing the context of a bus specific
|
||||
/// [`Device`].
|
||||
///
|
||||
/// This is the marker trait for structures representing the context of a bus specific device.
|
||||
/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`].
|
||||
///
|
||||
/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that
|
||||
/// defines which [`DeviceContext`] type can be derived from another. For instance, any
|
||||
/// [`Device<Core>`] can dereference to a [`Device<Bound>`].
|
||||
///
|
||||
/// The following enumeration illustrates the dereference hierarchy of [`DeviceContext`] types.
|
||||
///
|
||||
/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`]
|
||||
///
|
||||
/// Bus devices can automatically implement the dereference hierarchy by using
|
||||
/// [`impl_device_context_deref`].
|
||||
///
|
||||
/// Note that the guarantee for a [`Device`] reference to have a certain [`DeviceContext`] comes
|
||||
/// from the specific scope the [`Device`] reference is valid in.
|
||||
///
|
||||
/// [`impl_device_context_deref`]: kernel::impl_device_context_deref
|
||||
pub trait DeviceContext: private::Sealed {}
|
||||
|
||||
/// The [`Normal`] context is the context of a bus specific device when it is not an argument of
|
||||
/// any bus callback.
|
||||
/// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`].
|
||||
///
|
||||
/// The normal context does not indicate any specific context. Any `Device<Ctx>` is also a valid
|
||||
/// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement
|
||||
/// [`AlwaysRefCounted`] for.
|
||||
///
|
||||
/// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted
|
||||
pub struct Normal;
|
||||
|
||||
/// The [`Core`] context is the context of a bus specific device when it is supplied as argument of
|
||||
/// any of the bus callbacks, such as `probe()`.
|
||||
/// The [`Core`] context is the context of a bus specific device when it appears as argument of
|
||||
/// any bus specific callback, such as `probe()`.
|
||||
///
|
||||
/// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus
|
||||
/// callback it appears in. It is intended to be used for synchronization purposes. Bus device
|
||||
/// implementations can implement methods for [`Device<Core>`], such that they can only be called
|
||||
/// from bus callbacks.
|
||||
pub struct Core;
|
||||
|
||||
/// Semantically the same as [`Core`] but reserved for internal usage of the corresponding bus
|
||||
/// Semantically the same as [`Core`], but reserved for internal usage of the corresponding bus
|
||||
/// abstraction.
|
||||
///
|
||||
/// The internal core context is intended to be used in exactly the same way as the [`Core`]
|
||||
/// context, with the difference that this [`DeviceContext`] is internal to the corresponding bus
|
||||
/// abstraction.
|
||||
///
|
||||
/// This context mainly exists to share generic [`Device`] infrastructure that should only be called
|
||||
/// from bus callbacks with bus abstractions, but without making them accessible for drivers.
|
||||
pub struct CoreInternal;
|
||||
|
||||
/// The [`Bound`] context is the context of a bus specific device reference when it is guaranteed to
|
||||
/// be bound for the duration of its lifetime.
|
||||
/// The [`Bound`] context is the [`DeviceContext`] of a bus specific device when it is guaranteed to
|
||||
/// be bound to a driver.
|
||||
///
|
||||
/// The bound context indicates that for the entire duration of the lifetime of a [`Device<Bound>`]
|
||||
/// reference, the [`Device`] is guaranteed to be bound to a driver.
|
||||
///
|
||||
/// Some APIs, such as [`dma::CoherentAllocation`] or [`Devres`] rely on the [`Device`] to be bound,
|
||||
/// which can be proven with the [`Bound`] device context.
|
||||
///
|
||||
/// Any abstraction that can guarantee a scope where the corresponding bus device is bound, should
|
||||
/// provide a [`Device<Bound>`] reference to its users for this scope. This allows users to benefit
|
||||
/// from optimizations for accessing device resources, see also [`Devres::access`].
|
||||
///
|
||||
/// [`Devres`]: kernel::devres::Devres
|
||||
/// [`Devres::access`]: kernel::devres::Devres::access
|
||||
/// [`dma::CoherentAllocation`]: kernel::dma::CoherentAllocation
|
||||
pub struct Bound;
|
||||
|
||||
mod private {
|
||||
|
@ -115,10 +115,11 @@ pub struct Devres<T: Send> {
|
||||
/// Contains all the fields shared with [`Self::callback`].
|
||||
// TODO: Replace with `UnsafePinned`, once available.
|
||||
//
|
||||
// Subsequently, the `drop_in_place()` in `Devres::drop` and the explicit `Send` and `Sync'
|
||||
// impls can be removed.
|
||||
// Subsequently, the `drop_in_place()` in `Devres::drop` and `Devres::new` as well as the
|
||||
// explicit `Send` and `Sync' impls can be removed.
|
||||
#[pin]
|
||||
inner: Opaque<Inner<T>>,
|
||||
_add_action: (),
|
||||
}
|
||||
|
||||
impl<T: Send> Devres<T> {
|
||||
@ -140,7 +141,15 @@ impl<T: Send> Devres<T> {
|
||||
dev: dev.into(),
|
||||
callback,
|
||||
// INVARIANT: `inner` is properly initialized.
|
||||
inner <- {
|
||||
inner <- Opaque::pin_init(try_pin_init!(Inner {
|
||||
devm <- Completion::new(),
|
||||
revoke <- Completion::new(),
|
||||
data <- Revocable::new(data),
|
||||
})),
|
||||
// TODO: Replace with "initializer code blocks" [1] once available.
|
||||
//
|
||||
// [1] https://github.com/Rust-for-Linux/pin-init/pull/69
|
||||
_add_action: {
|
||||
// SAFETY: `this` is a valid pointer to uninitialized memory.
|
||||
let inner = unsafe { &raw mut (*this.as_ptr()).inner };
|
||||
|
||||
@ -152,13 +161,13 @@ impl<T: Send> Devres<T> {
|
||||
// live at least as long as the returned `impl PinInit<Self, Error>`.
|
||||
to_result(unsafe {
|
||||
bindings::devm_add_action(dev.as_raw(), Some(callback), inner.cast())
|
||||
})?;
|
||||
}).inspect_err(|_| {
|
||||
let inner = Opaque::cast_into(inner);
|
||||
|
||||
Opaque::pin_init(try_pin_init!(Inner {
|
||||
devm <- Completion::new(),
|
||||
revoke <- Completion::new(),
|
||||
data <- Revocable::new(data),
|
||||
}))
|
||||
// SAFETY: `inner` is a valid pointer to an `Inner<T>` and valid for both reads
|
||||
// and writes.
|
||||
unsafe { core::ptr::drop_in_place(inner) };
|
||||
})?;
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -2,8 +2,93 @@
|
||||
|
||||
//! Generic support for drivers of different buses (e.g., PCI, Platform, Amba, etc.).
|
||||
//!
|
||||
//! Each bus / subsystem is expected to implement [`RegistrationOps`], which allows drivers to
|
||||
//! register using the [`Registration`] class.
|
||||
//! This documentation describes how to implement a bus specific driver API and how to align it with
|
||||
//! the design of (bus specific) devices.
|
||||
//!
|
||||
//! Note: Readers are expected to know the content of the documentation of [`Device`] and
|
||||
//! [`DeviceContext`].
|
||||
//!
|
||||
//! # Driver Trait
|
||||
//!
|
||||
//! The main driver interface is defined by a bus specific driver trait. For instance:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! pub trait Driver: Send {
|
||||
//! /// The type holding information about each device ID supported by the driver.
|
||||
//! type IdInfo: 'static;
|
||||
//!
|
||||
//! /// The table of OF device ids supported by the driver.
|
||||
//! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
||||
//!
|
||||
//! /// The table of ACPI device ids supported by the driver.
|
||||
//! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;
|
||||
//!
|
||||
//! /// Driver probe.
|
||||
//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>;
|
||||
//!
|
||||
//! /// Driver unbind (optional).
|
||||
//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
|
||||
//! let _ = (dev, this);
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! For specific examples see [`auxiliary::Driver`], [`pci::Driver`] and [`platform::Driver`].
|
||||
//!
|
||||
//! The `probe()` callback should return a `Result<Pin<KBox<Self>>>`, i.e. the driver's private
|
||||
//! data. The bus abstraction should store the pointer in the corresponding bus device. The generic
|
||||
//! [`Device`] infrastructure provides common helpers for this purpose on its
|
||||
//! [`Device<CoreInternal>`] implementation.
|
||||
//!
|
||||
//! All driver callbacks should provide a reference to the driver's private data. Once the driver
|
||||
//! is unbound from the device, the bus abstraction should take back the ownership of the driver's
|
||||
//! private data from the corresponding [`Device`] and [`drop`] it.
|
||||
//!
|
||||
//! All driver callbacks should provide a [`Device<Core>`] reference (see also [`device::Core`]).
|
||||
//!
|
||||
//! # Adapter
|
||||
//!
|
||||
//! The adapter implementation of a bus represents the abstraction layer between the C bus
|
||||
//! callbacks and the Rust bus callbacks. It therefore has to be generic over an implementation of
|
||||
//! the [driver trait](#driver-trait).
|
||||
//!
|
||||
//! ```ignore
|
||||
//! pub struct Adapter<T: Driver>;
|
||||
//! ```
|
||||
//!
|
||||
//! There's a common [`Adapter`] trait that can be implemented to inherit common driver
|
||||
//! infrastructure, such as finding the ID info from an [`of::IdTable`] or [`acpi::IdTable`].
|
||||
//!
|
||||
//! # Driver Registration
|
||||
//!
|
||||
//! In order to register C driver types (such as `struct platform_driver`) the [adapter](#adapter)
|
||||
//! should implement the [`RegistrationOps`] trait.
|
||||
//!
|
||||
//! This trait implementation can be used to create the actual registration with the common
|
||||
//! [`Registration`] type.
|
||||
//!
|
||||
//! Typically, bus abstractions want to provide a bus specific `module_bus_driver!` macro, which
|
||||
//! creates a kernel module with exactly one [`Registration`] for the bus specific adapter.
|
||||
//!
|
||||
//! The generic driver infrastructure provides a helper for this with the [`module_driver`] macro.
|
||||
//!
|
||||
//! # Device IDs
|
||||
//!
|
||||
//! Besides the common device ID types, such as [`of::DeviceId`] and [`acpi::DeviceId`], most buses
|
||||
//! may need to implement their own device ID types.
|
||||
//!
|
||||
//! For this purpose the generic infrastructure in [`device_id`] should be used.
|
||||
//!
|
||||
//! [`auxiliary::Driver`]: kernel::auxiliary::Driver
|
||||
//! [`Core`]: device::Core
|
||||
//! [`Device`]: device::Device
|
||||
//! [`Device<Core>`]: device::Device<device::Core>
|
||||
//! [`Device<CoreInternal>`]: device::Device<device::CoreInternal>
|
||||
//! [`DeviceContext`]: device::DeviceContext
|
||||
//! [`device_id`]: kernel::device_id
|
||||
//! [`module_driver`]: kernel::module_driver
|
||||
//! [`pci::Driver`]: kernel::pci::Driver
|
||||
//! [`platform::Driver`]: kernel::platform::Driver
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule};
|
||||
|
@ -4,7 +4,7 @@
|
||||
//!
|
||||
//! This module provides bindings for working with faux devices in kernel modules.
|
||||
//!
|
||||
//! C header: [`include/linux/device/faux.h`]
|
||||
//! C header: [`include/linux/device/faux.h`](srctree/include/linux/device/faux.h)
|
||||
|
||||
use crate::{bindings, device, error::code::*, prelude::*};
|
||||
use core::ptr::{addr_of_mut, null, null_mut, NonNull};
|
||||
|
Loading…
Reference in New Issue
Block a user