mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
rust: driver: decouple driver private data from driver type
Add a type Data<'bound> associated type to all bus driver traits, decoupling the driver's bus device private data type from the driver struct itself. In the context of adding a 'bound lifetime, making this an associated type has the advantage that it allows us to avoid a driver trait global lifetime and it avoids the need for ForLt for bus device private data; both of which make the subsequent implementation by buses much simpler. All existing drivers and doc examples set type Data = Self to preserve the current behavior. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://patch.msgid.link/20260525202921.124698-5-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
@@ -201,6 +201,7 @@ kernel::of_device_table!(
|
||||
|
||||
impl platform::Driver for CPUFreqDTDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
|
||||
fn probe(
|
||||
|
||||
@@ -51,6 +51,7 @@ kernel::auxiliary_device_table!(
|
||||
|
||||
impl auxiliary::Driver for NovaDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
|
||||
|
||||
fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
|
||||
|
||||
@@ -91,6 +91,7 @@ kernel::of_device_table!(
|
||||
|
||||
impl platform::Driver for TyrPlatformDriverData {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
|
||||
fn probe(
|
||||
|
||||
@@ -74,6 +74,7 @@ kernel::pci_device_table!(
|
||||
|
||||
impl pci::Driver for NovaCore {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
|
||||
|
||||
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
|
||||
|
||||
@@ -316,6 +316,7 @@ kernel::of_device_table!(
|
||||
|
||||
impl platform::Driver for Th1520PwmPlatformDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
|
||||
fn probe(
|
||||
|
||||
@@ -41,12 +41,12 @@ pub struct Adapter<T: Driver>(T);
|
||||
|
||||
// SAFETY:
|
||||
// - `bindings::auxiliary_driver` is a C type declared as `repr(C)`.
|
||||
// - `T` is the type of the driver's device private data.
|
||||
// - `T::Data` is the type of the driver's device private data.
|
||||
// - `struct auxiliary_driver` embeds a `struct device_driver`.
|
||||
// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
|
||||
unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
|
||||
type DriverType = bindings::auxiliary_driver;
|
||||
type DriverData = T;
|
||||
type DriverData<'bound> = T::Data;
|
||||
const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
|
||||
}
|
||||
|
||||
@@ -111,8 +111,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `remove_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { adev.as_ref().drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { adev.as_ref().drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::unbind(adev, data);
|
||||
}
|
||||
@@ -202,13 +202,17 @@ pub trait Driver {
|
||||
/// type IdInfo: 'static = ();
|
||||
type IdInfo: 'static;
|
||||
|
||||
/// The type of the driver's bus device private data.
|
||||
type Data: Send;
|
||||
|
||||
/// The table of device ids supported by the driver.
|
||||
const ID_TABLE: IdTable<Self::IdInfo>;
|
||||
|
||||
/// Auxiliary driver probe.
|
||||
///
|
||||
/// Called when an auxiliary device is matches a corresponding driver.
|
||||
fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;
|
||||
fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
|
||||
-> impl PinInit<Self::Data, Error>;
|
||||
|
||||
/// Auxiliary driver unbind.
|
||||
///
|
||||
@@ -219,8 +223,8 @@ pub trait Driver {
|
||||
/// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
|
||||
/// operations to gracefully tear down the device.
|
||||
///
|
||||
/// Otherwise, release operations for driver resources should be performed in `Self::drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
|
||||
/// Otherwise, release operations for driver resources should be performed in `Drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
|
||||
let _ = (dev, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,6 +888,7 @@ pub trait Driver {
|
||||
///
|
||||
/// impl platform::Driver for SampleDriver {
|
||||
/// type IdInfo = ();
|
||||
/// type Data = Self;
|
||||
/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
||||
///
|
||||
/// fn probe(
|
||||
|
||||
+14
-10
@@ -13,10 +13,13 @@
|
||||
//! The main driver interface is defined by a bus specific driver trait. For instance:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! pub trait Driver: Send {
|
||||
//! pub trait Driver {
|
||||
//! /// The type holding information about each device ID supported by the driver.
|
||||
//! type IdInfo: 'static;
|
||||
//!
|
||||
//! /// The type of the driver's bus device private data.
|
||||
//! type Data: Send;
|
||||
//!
|
||||
//! /// The table of OF device ids supported by the driver.
|
||||
//! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
||||
//!
|
||||
@@ -24,10 +27,11 @@
|
||||
//! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;
|
||||
//!
|
||||
//! /// Driver probe.
|
||||
//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;
|
||||
//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
|
||||
//! -> impl PinInit<Self::Data, Error>;
|
||||
//!
|
||||
//! /// Driver unbind (optional).
|
||||
//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
|
||||
//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
|
||||
//! let _ = (dev, this);
|
||||
//! }
|
||||
//! }
|
||||
@@ -42,9 +46,9 @@
|
||||
)]
|
||||
#")]
|
||||
//!
|
||||
//! The `probe()` callback should return a `impl PinInit<Self, Error>`, 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
|
||||
//! The `probe()` callback should return a `impl PinInit<Self::Data, Error>`, 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
|
||||
@@ -118,8 +122,8 @@ pub unsafe trait DriverLayout {
|
||||
/// The specific driver type embedding a `struct device_driver`.
|
||||
type DriverType: Default;
|
||||
|
||||
/// The type of the driver's device private data.
|
||||
type DriverData;
|
||||
/// The type of the driver's bus device private data.
|
||||
type DriverData<'bound>;
|
||||
|
||||
/// Byte offset of the embedded `struct device_driver` within `DriverType`.
|
||||
///
|
||||
@@ -193,8 +197,8 @@ impl<T: RegistrationOps> Registration<T> {
|
||||
// driver's device private data.
|
||||
//
|
||||
// SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the
|
||||
// driver's device private data type.
|
||||
drop(unsafe { dev.drvdata_obtain::<T::DriverData>() });
|
||||
// driver's bus device private data type.
|
||||
drop(unsafe { dev.drvdata_obtain::<T::DriverData<'_>>() });
|
||||
}
|
||||
|
||||
/// Attach generic `struct device_driver` callbacks.
|
||||
|
||||
+18
-14
@@ -93,12 +93,12 @@ pub struct Adapter<T: Driver>(T);
|
||||
|
||||
// SAFETY:
|
||||
// - `bindings::i2c_driver` is a C type declared as `repr(C)`.
|
||||
// - `T` is the type of the driver's device private data.
|
||||
// - `T::Data` is the type of the driver's device private data.
|
||||
// - `struct i2c_driver` embeds a `struct device_driver`.
|
||||
// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
|
||||
unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
|
||||
type DriverType = bindings::i2c_driver;
|
||||
type DriverData = T;
|
||||
type DriverData<'bound> = T::Data;
|
||||
const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
|
||||
}
|
||||
|
||||
@@ -176,8 +176,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `remove_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { idev.as_ref().drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::unbind(idev, data);
|
||||
}
|
||||
@@ -188,8 +188,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `shutdown_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { idev.as_ref().drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::shutdown(idev, data);
|
||||
}
|
||||
@@ -294,6 +294,7 @@ macro_rules! module_i2c_driver {
|
||||
///
|
||||
/// impl i2c::Driver for MyDriver {
|
||||
/// type IdInfo = ();
|
||||
/// type Data = Self;
|
||||
/// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);
|
||||
/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
@@ -301,15 +302,15 @@ macro_rules! module_i2c_driver {
|
||||
/// fn probe(
|
||||
/// _idev: &i2c::I2cClient<Core>,
|
||||
/// _id_info: Option<&Self::IdInfo>,
|
||||
/// ) -> impl PinInit<Self, Error> {
|
||||
/// ) -> impl PinInit<Self::Data, Error> {
|
||||
/// Err(ENODEV)
|
||||
/// }
|
||||
///
|
||||
/// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self>) {
|
||||
/// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self::Data>) {
|
||||
/// }
|
||||
/// }
|
||||
///```
|
||||
pub trait Driver: Send {
|
||||
pub trait Driver {
|
||||
/// The type holding information about each device id supported by the driver.
|
||||
// TODO: Use `associated_type_defaults` once stabilized:
|
||||
//
|
||||
@@ -318,6 +319,9 @@ pub trait Driver: Send {
|
||||
// ```
|
||||
type IdInfo: 'static;
|
||||
|
||||
/// The type of the driver's bus device private data.
|
||||
type Data: Send;
|
||||
|
||||
/// The table of device ids supported by the driver.
|
||||
const I2C_ID_TABLE: Option<IdTable<Self::IdInfo>> = None;
|
||||
|
||||
@@ -334,7 +338,7 @@ pub trait Driver: Send {
|
||||
fn probe(
|
||||
dev: &I2cClient<device::Core>,
|
||||
id_info: Option<&Self::IdInfo>,
|
||||
) -> impl PinInit<Self, Error>;
|
||||
) -> impl PinInit<Self::Data, Error>;
|
||||
|
||||
/// I2C driver shutdown.
|
||||
///
|
||||
@@ -346,8 +350,8 @@ pub trait Driver: Send {
|
||||
///
|
||||
/// This callback is distinct from final resource cleanup, as the driver instance remains valid
|
||||
/// after it returns. Any deallocation or teardown of driver-owned resources should instead be
|
||||
/// handled in `Self::drop`.
|
||||
fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>) {
|
||||
/// handled in `Drop`.
|
||||
fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self::Data>) {
|
||||
let _ = (dev, this);
|
||||
}
|
||||
|
||||
@@ -360,8 +364,8 @@ pub trait Driver: Send {
|
||||
/// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
|
||||
/// operations to gracefully tear down the device.
|
||||
///
|
||||
/// Otherwise, release operations for driver resources should be performed in `Self::drop`.
|
||||
fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>) {
|
||||
/// Otherwise, release operations for driver resources should be performed in `Drop`.
|
||||
fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self::Data>) {
|
||||
let _ = (dev, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ impl<'a> IoRequest<'a> {
|
||||
///
|
||||
/// impl platform::Driver for SampleDriver {
|
||||
/// # type IdInfo = ();
|
||||
/// # type Data = Self;
|
||||
///
|
||||
/// fn probe(
|
||||
/// pdev: &platform::Device<Core>,
|
||||
@@ -126,6 +127,7 @@ impl<'a> IoRequest<'a> {
|
||||
///
|
||||
/// impl platform::Driver for SampleDriver {
|
||||
/// # type IdInfo = ();
|
||||
/// # type Data = Self;
|
||||
///
|
||||
/// fn probe(
|
||||
/// pdev: &platform::Device<Core>,
|
||||
|
||||
+13
-8
@@ -59,12 +59,12 @@ pub struct Adapter<T: Driver>(T);
|
||||
|
||||
// SAFETY:
|
||||
// - `bindings::pci_driver` is a C type declared as `repr(C)`.
|
||||
// - `T` is the type of the driver's device private data.
|
||||
// - `T::Data` is the type of the driver's device private data.
|
||||
// - `struct pci_driver` embeds a `struct device_driver`.
|
||||
// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
|
||||
unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
|
||||
type DriverType = bindings::pci_driver;
|
||||
type DriverData = T;
|
||||
type DriverData<'bound> = T::Data;
|
||||
const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
|
||||
}
|
||||
|
||||
@@ -129,8 +129,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `remove_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { pdev.as_ref().drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::unbind(pdev, data);
|
||||
}
|
||||
@@ -279,6 +279,7 @@ macro_rules! pci_device_table {
|
||||
///
|
||||
/// impl pci::Driver for MyDriver {
|
||||
/// type IdInfo = ();
|
||||
/// type Data = Self;
|
||||
/// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
|
||||
///
|
||||
/// fn probe(
|
||||
@@ -291,7 +292,7 @@ macro_rules! pci_device_table {
|
||||
///```
|
||||
/// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the
|
||||
/// `Adapter` documentation for an example.
|
||||
pub trait Driver: Send {
|
||||
pub trait Driver {
|
||||
/// The type holding information about each device id supported by the driver.
|
||||
// TODO: Use `associated_type_defaults` once stabilized:
|
||||
//
|
||||
@@ -300,6 +301,9 @@ pub trait Driver: Send {
|
||||
// ```
|
||||
type IdInfo: 'static;
|
||||
|
||||
/// The type of the driver's bus device private data.
|
||||
type Data: Send;
|
||||
|
||||
/// The table of device ids supported by the driver.
|
||||
const ID_TABLE: IdTable<Self::IdInfo>;
|
||||
|
||||
@@ -307,7 +311,8 @@ pub trait Driver: Send {
|
||||
///
|
||||
/// Called when a new pci device is added or discovered. Implementers should
|
||||
/// attempt to initialize the device here.
|
||||
fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;
|
||||
fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
|
||||
-> impl PinInit<Self::Data, Error>;
|
||||
|
||||
/// PCI driver unbind.
|
||||
///
|
||||
@@ -318,8 +323,8 @@ pub trait Driver: Send {
|
||||
/// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
|
||||
/// operations to gracefully tear down the device.
|
||||
///
|
||||
/// Otherwise, release operations for driver resources should be performed in `Self::drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
|
||||
/// Otherwise, release operations for driver resources should be performed in `Drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
|
||||
let _ = (dev, this);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -45,12 +45,12 @@ pub struct Adapter<T: Driver>(T);
|
||||
|
||||
// SAFETY:
|
||||
// - `bindings::platform_driver` is a C type declared as `repr(C)`.
|
||||
// - `T` is the type of the driver's device private data.
|
||||
// - `T::Data` is the type of the driver's device private data.
|
||||
// - `struct platform_driver` embeds a `struct device_driver`.
|
||||
// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
|
||||
unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
|
||||
type DriverType = bindings::platform_driver;
|
||||
type DriverData = T;
|
||||
type DriverData<'bound> = T::Data;
|
||||
const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
|
||||
}
|
||||
|
||||
@@ -117,8 +117,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `remove_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { pdev.as_ref().drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::unbind(pdev, data);
|
||||
}
|
||||
@@ -192,6 +192,7 @@ macro_rules! module_platform_driver {
|
||||
///
|
||||
/// impl platform::Driver for MyDriver {
|
||||
/// type IdInfo = ();
|
||||
/// type Data = Self;
|
||||
/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
///
|
||||
@@ -203,7 +204,7 @@ macro_rules! module_platform_driver {
|
||||
/// }
|
||||
/// }
|
||||
///```
|
||||
pub trait Driver: Send {
|
||||
pub trait Driver {
|
||||
/// The type holding driver private data about each device id supported by the driver.
|
||||
// TODO: Use associated_type_defaults once stabilized:
|
||||
//
|
||||
@@ -212,6 +213,9 @@ pub trait Driver: Send {
|
||||
// ```
|
||||
type IdInfo: 'static;
|
||||
|
||||
/// The type of the driver's bus device private data.
|
||||
type Data: Send;
|
||||
|
||||
/// The table of OF device ids supported by the driver.
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
||||
|
||||
@@ -225,7 +229,7 @@ pub trait Driver: Send {
|
||||
fn probe(
|
||||
dev: &Device<device::Core>,
|
||||
id_info: Option<&Self::IdInfo>,
|
||||
) -> impl PinInit<Self, Error>;
|
||||
) -> impl PinInit<Self::Data, Error>;
|
||||
|
||||
/// Platform driver unbind.
|
||||
///
|
||||
@@ -236,8 +240,8 @@ pub trait Driver: Send {
|
||||
/// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
|
||||
/// operations to gracefully tear down the device.
|
||||
///
|
||||
/// Otherwise, release operations for driver resources should be performed in `Self::drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
|
||||
/// Otherwise, release operations for driver resources should be performed in `Drop`.
|
||||
fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
|
||||
let _ = (dev, this);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -36,12 +36,12 @@ pub struct Adapter<T: Driver>(T);
|
||||
|
||||
// SAFETY:
|
||||
// - `bindings::usb_driver` is a C type declared as `repr(C)`.
|
||||
// - `T` is the type of the driver's device private data.
|
||||
// - `T::Data` is the type of the driver's device private data.
|
||||
// - `struct usb_driver` embeds a `struct device_driver`.
|
||||
// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
|
||||
unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
|
||||
type DriverType = bindings::usb_driver;
|
||||
type DriverData = T;
|
||||
type DriverData<'bound> = T::Data;
|
||||
const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
|
||||
}
|
||||
|
||||
@@ -109,8 +109,8 @@ impl<T: Driver> Adapter<T> {
|
||||
|
||||
// SAFETY: `disconnect_callback` is only ever called after a successful call to
|
||||
// `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
|
||||
// and stored a `Pin<KBox<T>>`.
|
||||
let data = unsafe { dev.drvdata_borrow::<T>() };
|
||||
// and stored a `Pin<KBox<T::Data>>`.
|
||||
let data = unsafe { dev.drvdata_borrow::<T::Data>() };
|
||||
|
||||
T::disconnect(intf, data);
|
||||
}
|
||||
@@ -287,23 +287,27 @@ macro_rules! usb_device_table {
|
||||
///
|
||||
/// impl usb::Driver for MyDriver {
|
||||
/// type IdInfo = ();
|
||||
/// type Data = Self;
|
||||
/// const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;
|
||||
///
|
||||
/// fn probe(
|
||||
/// _interface: &usb::Interface<Core>,
|
||||
/// _id: &usb::DeviceId,
|
||||
/// _info: &Self::IdInfo,
|
||||
/// ) -> impl PinInit<Self, Error> {
|
||||
/// ) -> impl PinInit<Self::Data, Error> {
|
||||
/// Err(ENODEV)
|
||||
/// }
|
||||
///
|
||||
/// fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self>) {}
|
||||
/// fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self::Data>) {}
|
||||
/// }
|
||||
///```
|
||||
pub trait Driver {
|
||||
/// The type holding information about each one of the device ids supported by the driver.
|
||||
type IdInfo: 'static;
|
||||
|
||||
/// The type of the driver's bus device private data.
|
||||
type Data: Send;
|
||||
|
||||
/// The table of device ids supported by the driver.
|
||||
const ID_TABLE: IdTable<Self::IdInfo>;
|
||||
|
||||
@@ -315,12 +319,12 @@ pub trait Driver {
|
||||
interface: &Interface<device::Core>,
|
||||
id: &DeviceId,
|
||||
id_info: &Self::IdInfo,
|
||||
) -> impl PinInit<Self, Error>;
|
||||
) -> impl PinInit<Self::Data, Error>;
|
||||
|
||||
/// USB driver disconnect.
|
||||
///
|
||||
/// Called when the USB interface is about to be unbound from this driver.
|
||||
fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self>);
|
||||
fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self::Data>);
|
||||
}
|
||||
|
||||
/// A USB interface.
|
||||
|
||||
@@ -117,6 +117,7 @@ kernel::acpi_device_table!(
|
||||
|
||||
impl platform::Driver for RustDebugFs {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
||||
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ kernel::pci_device_table!(
|
||||
|
||||
impl pci::Driver for DmaSampleDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
|
||||
|
||||
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
|
||||
|
||||
@@ -31,6 +31,7 @@ kernel::auxiliary_device_table!(
|
||||
|
||||
impl auxiliary::Driver for AuxiliaryDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
|
||||
const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
|
||||
|
||||
@@ -65,6 +66,7 @@ kernel::pci_device_table!(
|
||||
|
||||
impl pci::Driver for ParentDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
|
||||
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ kernel::of_device_table! {
|
||||
|
||||
impl i2c::Driver for SampleDriver {
|
||||
type IdInfo = u32;
|
||||
type Data = Self;
|
||||
|
||||
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);
|
||||
|
||||
@@ -140,6 +140,7 @@ impl SampleDriver {
|
||||
|
||||
impl pci::Driver for SampleDriver {
|
||||
type IdInfo = TestIndex;
|
||||
type Data = Self;
|
||||
|
||||
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ kernel::acpi_device_table!(
|
||||
|
||||
impl platform::Driver for SampleDriver {
|
||||
type IdInfo = Info;
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ kernel::usb_device_table!(
|
||||
|
||||
impl usb::Driver for SampleDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;
|
||||
|
||||
fn probe(
|
||||
|
||||
@@ -106,6 +106,7 @@ const BOARD_INFO: i2c::I2cBoardInfo =
|
||||
|
||||
impl platform::Driver for SampleDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ kernel::acpi_device_table!(
|
||||
|
||||
impl platform::Driver for SampleSocDriver {
|
||||
type IdInfo = ();
|
||||
type Data = Self;
|
||||
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
||||
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user