History

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.

Danilo Krummrich committed 5 months ago

Commit 7fdffdd1 parent c8a436622 files · +98 −55Browse files

Unified · Split

22 files
  1. drivers/cpufreq/rcpufreq_dt.rs +1 −0
  2. drivers/gpu/drm/nova/driver.rs +1 −0
  3. drivers/gpu/drm/tyr/driver.rs +1 −0
  4. drivers/gpu/nova-core/driver.rs +1 −0
  5. drivers/pwm/pwm_th1520.rs +1 −0
  6. rust/kernel/auxiliary.rs +11 −7
  7. rust/kernel/cpufreq.rs +1 −0
  8. rust/kernel/driver.rs +14 −10
  9. rust/kernel/i2c.rs +18 −14
  10. rust/kernel/io/mem.rs +2 −0
  11. rust/kernel/pci.rs +13 −8
  12. rust/kernel/platform.rs +12 −8
  13. rust/kernel/usb.rs +12 −8
  14. samples/rust/rust_debugfs.rs +1 −0
  15. samples/rust/rust_dma.rs +1 −0
  16. samples/rust/rust_driver_auxiliary.rs +2 −0
  17. samples/rust/rust_driver_i2c.rs +1 −0
  18. samples/rust/rust_driver_pci.rs +1 −0
  19. samples/rust/rust_driver_platform.rs +1 −0
  20. samples/rust/rust_driver_usb.rs +1 −0
  21. samples/rust/rust_i2c_client.rs +1 −0
  22. samples/rust/rust_soc.rs +1 −0
drivers/cpufreq/rcpufreq_dt.rs+1−0
@@ -201,6 +201,7 @@ kernel::of_device_table!( · 200 unmodified lines
201 201
202impl platform::Driver for CPUFreqDTDriver {202impl platform::Driver for CPUFreqDTDriver {
203 type IdInfo = ();203 type IdInfo = ();
204 type Data = Self;
204 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);205 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
205 206
206 fn probe(207 fn probe(
drivers/gpu/drm/nova/driver.rs+1−0
@@ -51,6 +51,7 @@ kernel::auxiliary_device_table!( · 50 unmodified lines
51 51
52impl auxiliary::Driver for NovaDriver {52impl auxiliary::Driver for NovaDriver {
53 type IdInfo = ();53 type IdInfo = ();
54 type Data = Self;
54 const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;55 const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
55 56
56 fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {57 fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
drivers/gpu/drm/tyr/driver.rs+1−0
@@ -91,6 +91,7 @@ kernel::of_device_table!( · 90 unmodified lines
91 91
92impl platform::Driver for TyrPlatformDriverData {92impl platform::Driver for TyrPlatformDriverData {
93 type IdInfo = ();93 type IdInfo = ();
94 type Data = Self;
94 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);95 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
95 96
96 fn probe(97 fn probe(
drivers/gpu/nova-core/driver.rs+1−0
@@ -74,6 +74,7 @@ kernel::pci_device_table!( · 73 unmodified lines
74 74
75impl pci::Driver for NovaCore {75impl pci::Driver for NovaCore {
76 type IdInfo = ();76 type IdInfo = ();
77 type Data = Self;
77 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;78 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
78 79
79 fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {80 fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
drivers/pwm/pwm_th1520.rs+1−0
@@ -316,6 +316,7 @@ kernel::of_device_table!( · 315 unmodified lines
316 316
317impl platform::Driver for Th1520PwmPlatformDriver {317impl platform::Driver for Th1520PwmPlatformDriver {
318 type IdInfo = ();318 type IdInfo = ();
319 type Data = Self;
319 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);320 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
320 321
321 fn probe(322 fn probe(
rust/kernel/auxiliary.rs+11−7
@@ -41,12 +41,12 @@ pub struct Adapter<T: Driver>(T); · 40 unmodified lines
41 41
42// SAFETY:42// SAFETY:
43// - `bindings::auxiliary_driver` is a C type declared as `repr(C)`.43// - `bindings::auxiliary_driver` is a C type declared as `repr(C)`.
44// - `T` is the type of the driver's device private data.44// - `T::Data` is the type of the driver's device private data.
45// - `struct auxiliary_driver` embeds a `struct device_driver`.45// - `struct auxiliary_driver` embeds a `struct device_driver`.
46// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.46// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
47unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {47unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
48 type DriverType = bindings::auxiliary_driver;48 type DriverType = bindings::auxiliary_driver;
49 type DriverData = T;49 type DriverData<'bound> = T::Data;
50 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);50 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
51}51}
52 52
@@ -111,8 +111,8 @@ impl<T: Driver> Adapter<T> { · 58 unmodified lines
111 111
112 // SAFETY: `remove_callback` is only ever called after a successful call to112 // SAFETY: `remove_callback` is only ever called after a successful call to
113 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called113 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
114 // and stored a `Pin<KBox<T>>`.114 // and stored a `Pin<KBox<T::Data>>`.
115 let data = unsafe { adev.as_ref().drvdata_borrow::<T>() };115 let data = unsafe { adev.as_ref().drvdata_borrow::<T::Data>() };
116 116
117 T::unbind(adev, data);117 T::unbind(adev, data);
118 }118 }
@@ -202,13 +202,17 @@ pub trait Driver { · 83 unmodified lines
202 /// type IdInfo: 'static = ();202 /// type IdInfo: 'static = ();
203 type IdInfo: 'static;203 type IdInfo: 'static;
204 204
205 /// The type of the driver's bus device private data.
206 type Data: Send;
207
205 /// The table of device ids supported by the driver.208 /// The table of device ids supported by the driver.
206 const ID_TABLE: IdTable<Self::IdInfo>;209 const ID_TABLE: IdTable<Self::IdInfo>;
207 210
208 /// Auxiliary driver probe.211 /// Auxiliary driver probe.
209 ///212 ///
210 /// Called when an auxiliary device is matches a corresponding driver.213 /// Called when an auxiliary device is matches a corresponding driver.
211 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;214 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
215 -> impl PinInit<Self::Data, Error>;
212 216
213 /// Auxiliary driver unbind.217 /// Auxiliary driver unbind.
214 ///218 ///
@@ -219,8 +223,8 @@ pub trait Driver { · 4 unmodified lines
219 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O223 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
220 /// operations to gracefully tear down the device.224 /// operations to gracefully tear down the device.
221 ///225 ///
222 /// Otherwise, release operations for driver resources should be performed in `Self::drop`.226 /// Otherwise, release operations for driver resources should be performed in `Drop`.
223 fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {227 fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
224 let _ = (dev, this);228 let _ = (dev, this);
225 }229 }
226}230}
rust/kernel/cpufreq.rs+1−0
@@ -888,6 +888,7 @@ pub trait Driver { · 887 unmodified lines
888///888///
889/// impl platform::Driver for SampleDriver {889/// impl platform::Driver for SampleDriver {
890/// type IdInfo = ();890/// type IdInfo = ();
891/// type Data = Self;
891/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;892/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
892///893///
893/// fn probe(894/// fn probe(
rust/kernel/driver.rs+14−10
@@ -13,10 +13,13 @@ · 12 unmodified lines
13//! The main driver interface is defined by a bus specific driver trait. For instance:13//! The main driver interface is defined by a bus specific driver trait. For instance:
14//!14//!
15//! ```ignore15//! ```ignore
16//! pub trait Driver: Send {16//! pub trait Driver {
17//! /// The type holding information about each device ID supported by the driver.17//! /// The type holding information about each device ID supported by the driver.
18//! type IdInfo: 'static;18//! type IdInfo: 'static;
19//!19//!
20//! /// The type of the driver's bus device private data.
21//! type Data: Send;
22//!
20//! /// The table of OF device ids supported by the driver.23//! /// The table of OF device ids supported by the driver.
21//! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;24//! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
22//!25//!
@@ -24,10 +27,11 @@ · 1 unmodified line
24//! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;27//! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;
25//!28//!
26//! /// Driver probe.29//! /// Driver probe.
27//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;30//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
31//! -> impl PinInit<Self::Data, Error>;
28//!32//!
29//! /// Driver unbind (optional).33//! /// Driver unbind (optional).
30//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {34//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
31//! let _ = (dev, this);35//! let _ = (dev, this);
32//! }36//! }
33//! }37//! }
@@ -42,9 +46,9 @@ · 8 unmodified lines
42)]46)]
43#![cfg_attr(CONFIG_PCI, doc = "* [`pci::Driver`](kernel::pci::Driver)")]47#![cfg_attr(CONFIG_PCI, doc = "* [`pci::Driver`](kernel::pci::Driver)")]
44//!48//!
45//! The `probe()` callback should return a `impl PinInit<Self, Error>`, i.e. the driver's private49//! The `probe()` callback should return a `impl PinInit<Self::Data, Error>`, i.e. the driver's
46//! data. The bus abstraction should store the pointer in the corresponding bus device. The generic50//! private data. The bus abstraction should store the pointer in the corresponding bus device. The
47//! [`Device`] infrastructure provides common helpers for this purpose on its51//! generic [`Device`] infrastructure provides common helpers for this purpose on its
48//! [`Device<CoreInternal>`] implementation.52//! [`Device<CoreInternal>`] implementation.
49//!53//!
50//! All driver callbacks should provide a reference to the driver's private data. Once the driver54//! All driver callbacks should provide a reference to the driver's private data. Once the driver
@@ -118,8 +122,8 @@ pub unsafe trait DriverLayout { · 67 unmodified lines
118 /// The specific driver type embedding a `struct device_driver`.122 /// The specific driver type embedding a `struct device_driver`.
119 type DriverType: Default;123 type DriverType: Default;
120 124
121 /// The type of the driver's device private data.125 /// The type of the driver's bus device private data.
122 type DriverData;126 type DriverData<'bound>;
123 127
124 /// Byte offset of the embedded `struct device_driver` within `DriverType`.128 /// Byte offset of the embedded `struct device_driver` within `DriverType`.
125 ///129 ///
@@ -193,8 +197,8 @@ impl<T: RegistrationOps> Registration<T> { · 67 unmodified lines
193 // driver's device private data.197 // driver's device private data.
194 //198 //
195 // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the199 // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the
196 // driver's device private data type.200 // driver's bus device private data type.
197 drop(unsafe { dev.drvdata_obtain::<T::DriverData>() });201 drop(unsafe { dev.drvdata_obtain::<T::DriverData<'_>>() });
198 }202 }
199 203
200 /// Attach generic `struct device_driver` callbacks.204 /// Attach generic `struct device_driver` callbacks.
rust/kernel/i2c.rs+18−14
@@ -93,12 +93,12 @@ pub struct Adapter<T: Driver>(T); · 92 unmodified lines
93 93
94// SAFETY:94// SAFETY:
95// - `bindings::i2c_driver` is a C type declared as `repr(C)`.95// - `bindings::i2c_driver` is a C type declared as `repr(C)`.
96// - `T` is the type of the driver's device private data.96// - `T::Data` is the type of the driver's device private data.
97// - `struct i2c_driver` embeds a `struct device_driver`.97// - `struct i2c_driver` embeds a `struct device_driver`.
98// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.98// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
99unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {99unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
100 type DriverType = bindings::i2c_driver;100 type DriverType = bindings::i2c_driver;
101 type DriverData = T;101 type DriverData<'bound> = T::Data;
102 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);102 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
103}103}
104 104
@@ -176,8 +176,8 @@ impl<T: Driver> Adapter<T> { · 71 unmodified lines
176 176
177 // SAFETY: `remove_callback` is only ever called after a successful call to177 // SAFETY: `remove_callback` is only ever called after a successful call to
178 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called178 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called
179 // and stored a `Pin<KBox<T>>`.179 // and stored a `Pin<KBox<T::Data>>`.
180 let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };180 let data = unsafe { idev.as_ref().drvdata_borrow::<T::Data>() };
181 181
182 T::unbind(idev, data);182 T::unbind(idev, data);
183 }183 }
@@ -188,8 +188,8 @@ impl<T: Driver> Adapter<T> { · 4 unmodified lines
188 188
189 // SAFETY: `shutdown_callback` is only ever called after a successful call to189 // SAFETY: `shutdown_callback` is only ever called after a successful call to
190 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called190 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
191 // and stored a `Pin<KBox<T>>`.191 // and stored a `Pin<KBox<T::Data>>`.
192 let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };192 let data = unsafe { idev.as_ref().drvdata_borrow::<T::Data>() };
193 193
194 T::shutdown(idev, data);194 T::shutdown(idev, data);
195 }195 }
@@ -294,6 +294,7 @@ macro_rules! module_i2c_driver { · 98 unmodified lines
294///294///
295/// impl i2c::Driver for MyDriver {295/// impl i2c::Driver for MyDriver {
296/// type IdInfo = ();296/// type IdInfo = ();
297/// type Data = Self;
297/// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);298/// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);
298/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);299/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
299/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);300/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
@@ -301,15 +302,15 @@ macro_rules! module_i2c_driver { · 1 unmodified line
301/// fn probe(302/// fn probe(
302/// _idev: &i2c::I2cClient<Core>,303/// _idev: &i2c::I2cClient<Core>,
303/// _id_info: Option<&Self::IdInfo>,304/// _id_info: Option<&Self::IdInfo>,
304/// ) -> impl PinInit<Self, Error> {305/// ) -> impl PinInit<Self::Data, Error> {
305/// Err(ENODEV)306/// Err(ENODEV)
306/// }307/// }
307///308///
308/// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self>) {309/// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self::Data>) {
309/// }310/// }
310/// }311/// }
311///```312///```
312pub trait Driver: Send {313pub trait Driver {
313 /// The type holding information about each device id supported by the driver.314 /// The type holding information about each device id supported by the driver.
314 // TODO: Use `associated_type_defaults` once stabilized:315 // TODO: Use `associated_type_defaults` once stabilized:
315 //316 //
@@ -318,6 +319,9 @@ pub trait Driver: Send { · 2 unmodified lines
318 // ```319 // ```
319 type IdInfo: 'static;320 type IdInfo: 'static;
320 321
322 /// The type of the driver's bus device private data.
323 type Data: Send;
324
321 /// The table of device ids supported by the driver.325 /// The table of device ids supported by the driver.
322 const I2C_ID_TABLE: Option<IdTable<Self::IdInfo>> = None;326 const I2C_ID_TABLE: Option<IdTable<Self::IdInfo>> = None;
323 327
@@ -334,7 +338,7 @@ pub trait Driver: Send { · 10 unmodified lines
334 fn probe(338 fn probe(
335 dev: &I2cClient<device::Core>,339 dev: &I2cClient<device::Core>,
336 id_info: Option<&Self::IdInfo>,340 id_info: Option<&Self::IdInfo>,
337 ) -> impl PinInit<Self, Error>;341 ) -> impl PinInit<Self::Data, Error>;
338 342
339 /// I2C driver shutdown.343 /// I2C driver shutdown.
340 ///344 ///
@@ -346,8 +350,8 @@ pub trait Driver: Send { · 5 unmodified lines
346 ///350 ///
347 /// This callback is distinct from final resource cleanup, as the driver instance remains valid351 /// This callback is distinct from final resource cleanup, as the driver instance remains valid
348 /// after it returns. Any deallocation or teardown of driver-owned resources should instead be352 /// after it returns. Any deallocation or teardown of driver-owned resources should instead be
349 /// handled in `Self::drop`.353 /// handled in `Drop`.
350 fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>) {354 fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self::Data>) {
351 let _ = (dev, this);355 let _ = (dev, this);
352 }356 }
353 357
@@ -360,8 +364,8 @@ pub trait Driver: Send { · 6 unmodified lines
360 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O364 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
361 /// operations to gracefully tear down the device.365 /// operations to gracefully tear down the device.
362 ///366 ///
363 /// Otherwise, release operations for driver resources should be performed in `Self::drop`.367 /// Otherwise, release operations for driver resources should be performed in `Drop`.
364 fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>) {368 fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self::Data>) {
365 let _ = (dev, this);369 let _ = (dev, this);
366 }370 }
367}371}
rust/kernel/io/mem.rs+2−0
@@ -62,6 +62,7 @@ impl<'a> IoRequest<'a> { · 61 unmodified lines
62 ///62 ///
63 /// impl platform::Driver for SampleDriver {63 /// impl platform::Driver for SampleDriver {
64 /// # type IdInfo = ();64 /// # type IdInfo = ();
65 /// # type Data = Self;
65 ///66 ///
66 /// fn probe(67 /// fn probe(
67 /// pdev: &platform::Device<Core>,68 /// pdev: &platform::Device<Core>,
@@ -126,6 +127,7 @@ impl<'a> IoRequest<'a> { · 58 unmodified lines
126 ///127 ///
127 /// impl platform::Driver for SampleDriver {128 /// impl platform::Driver for SampleDriver {
128 /// # type IdInfo = ();129 /// # type IdInfo = ();
130 /// # type Data = Self;
129 ///131 ///
130 /// fn probe(132 /// fn probe(
131 /// pdev: &platform::Device<Core>,133 /// pdev: &platform::Device<Core>,
rust/kernel/pci.rs+13−8
@@ -59,12 +59,12 @@ pub struct Adapter<T: Driver>(T); · 58 unmodified lines
59 59
60// SAFETY:60// SAFETY:
61// - `bindings::pci_driver` is a C type declared as `repr(C)`.61// - `bindings::pci_driver` is a C type declared as `repr(C)`.
62// - `T` is the type of the driver's device private data.62// - `T::Data` is the type of the driver's device private data.
63// - `struct pci_driver` embeds a `struct device_driver`.63// - `struct pci_driver` embeds a `struct device_driver`.
64// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.64// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
65unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {65unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
66 type DriverType = bindings::pci_driver;66 type DriverType = bindings::pci_driver;
67 type DriverData = T;67 type DriverData<'bound> = T::Data;
68 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);68 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
69}69}
70 70
@@ -129,8 +129,8 @@ impl<T: Driver> Adapter<T> { · 58 unmodified lines
129 129
130 // SAFETY: `remove_callback` is only ever called after a successful call to130 // SAFETY: `remove_callback` is only ever called after a successful call to
131 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called131 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
132 // and stored a `Pin<KBox<T>>`.132 // and stored a `Pin<KBox<T::Data>>`.
133 let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };133 let data = unsafe { pdev.as_ref().drvdata_borrow::<T::Data>() };
134 134
135 T::unbind(pdev, data);135 T::unbind(pdev, data);
136 }136 }
@@ -279,6 +279,7 @@ macro_rules! pci_device_table { · 142 unmodified lines
279///279///
280/// impl pci::Driver for MyDriver {280/// impl pci::Driver for MyDriver {
281/// type IdInfo = ();281/// type IdInfo = ();
282/// type Data = Self;
282/// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;283/// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
283///284///
284/// fn probe(285/// fn probe(
@@ -291,7 +292,7 @@ macro_rules! pci_device_table { · 6 unmodified lines
291///```292///```
292/// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the293/// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the
293/// `Adapter` documentation for an example.294/// `Adapter` documentation for an example.
294pub trait Driver: Send {295pub trait Driver {
295 /// The type holding information about each device id supported by the driver.296 /// The type holding information about each device id supported by the driver.
296 // TODO: Use `associated_type_defaults` once stabilized:297 // TODO: Use `associated_type_defaults` once stabilized:
297 //298 //
@@ -300,6 +301,9 @@ pub trait Driver: Send { · 2 unmodified lines
300 // ```301 // ```
301 type IdInfo: 'static;302 type IdInfo: 'static;
302 303
304 /// The type of the driver's bus device private data.
305 type Data: Send;
306
303 /// The table of device ids supported by the driver.307 /// The table of device ids supported by the driver.
304 const ID_TABLE: IdTable<Self::IdInfo>;308 const ID_TABLE: IdTable<Self::IdInfo>;
305 309
@@ -307,7 +311,8 @@ pub trait Driver: Send { · 1 unmodified line
307 ///311 ///
308 /// Called when a new pci device is added or discovered. Implementers should312 /// Called when a new pci device is added or discovered. Implementers should
309 /// attempt to initialize the device here.313 /// attempt to initialize the device here.
310 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;314 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo)
315 -> impl PinInit<Self::Data, Error>;
311 316
312 /// PCI driver unbind.317 /// PCI driver unbind.
313 ///318 ///
@@ -318,8 +323,8 @@ pub trait Driver: Send { · 4 unmodified lines
318 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O323 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
319 /// operations to gracefully tear down the device.324 /// operations to gracefully tear down the device.
320 ///325 ///
321 /// Otherwise, release operations for driver resources should be performed in `Self::drop`.326 /// Otherwise, release operations for driver resources should be performed in `Drop`.
322 fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {327 fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
323 let _ = (dev, this);328 let _ = (dev, this);
324 }329 }
325}330}
rust/kernel/platform.rs+12−8
@@ -45,12 +45,12 @@ pub struct Adapter<T: Driver>(T); · 44 unmodified lines
45 45
46// SAFETY:46// SAFETY:
47// - `bindings::platform_driver` is a C type declared as `repr(C)`.47// - `bindings::platform_driver` is a C type declared as `repr(C)`.
48// - `T` is the type of the driver's device private data.48// - `T::Data` is the type of the driver's device private data.
49// - `struct platform_driver` embeds a `struct device_driver`.49// - `struct platform_driver` embeds a `struct device_driver`.
50// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.50// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
51unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {51unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
52 type DriverType = bindings::platform_driver;52 type DriverType = bindings::platform_driver;
53 type DriverData = T;53 type DriverData<'bound> = T::Data;
54 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);54 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
55}55}
56 56
@@ -117,8 +117,8 @@ impl<T: Driver> Adapter<T> { · 60 unmodified lines
117 117
118 // SAFETY: `remove_callback` is only ever called after a successful call to118 // SAFETY: `remove_callback` is only ever called after a successful call to
119 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called119 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
120 // and stored a `Pin<KBox<T>>`.120 // and stored a `Pin<KBox<T::Data>>`.
121 let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };121 let data = unsafe { pdev.as_ref().drvdata_borrow::<T::Data>() };
122 122
123 T::unbind(pdev, data);123 T::unbind(pdev, data);
124 }124 }
@@ -192,6 +192,7 @@ macro_rules! module_platform_driver { · 67 unmodified lines
192///192///
193/// impl platform::Driver for MyDriver {193/// impl platform::Driver for MyDriver {
194/// type IdInfo = ();194/// type IdInfo = ();
195/// type Data = Self;
195/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);196/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
196/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);197/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
197///198///
@@ -203,7 +204,7 @@ macro_rules! module_platform_driver { · 5 unmodified lines
203/// }204/// }
204/// }205/// }
205///```206///```
206pub trait Driver: Send {207pub trait Driver {
207 /// The type holding driver private data about each device id supported by the driver.208 /// The type holding driver private data about each device id supported by the driver.
208 // TODO: Use associated_type_defaults once stabilized:209 // TODO: Use associated_type_defaults once stabilized:
209 //210 //
@@ -212,6 +213,9 @@ pub trait Driver: Send { · 2 unmodified lines
212 // ```213 // ```
213 type IdInfo: 'static;214 type IdInfo: 'static;
214 215
216 /// The type of the driver's bus device private data.
217 type Data: Send;
218
215 /// The table of OF device ids supported by the driver.219 /// The table of OF device ids supported by the driver.
216 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;220 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
217 221
@@ -225,7 +229,7 @@ pub trait Driver: Send { · 7 unmodified lines
225 fn probe(229 fn probe(
226 dev: &Device<device::Core>,230 dev: &Device<device::Core>,
227 id_info: Option<&Self::IdInfo>,231 id_info: Option<&Self::IdInfo>,
228 ) -> impl PinInit<Self, Error>;232 ) -> impl PinInit<Self::Data, Error>;
229 233
230 /// Platform driver unbind.234 /// Platform driver unbind.
231 ///235 ///
@@ -236,8 +240,8 @@ pub trait Driver: Send { · 4 unmodified lines
236 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O240 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
237 /// operations to gracefully tear down the device.241 /// operations to gracefully tear down the device.
238 ///242 ///
239 /// Otherwise, release operations for driver resources should be performed in `Self::drop`.243 /// Otherwise, release operations for driver resources should be performed in `Drop`.
240 fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {244 fn unbind(dev: &Device<device::Core>, this: Pin<&Self::Data>) {
241 let _ = (dev, this);245 let _ = (dev, this);
242 }246 }
243}247}
rust/kernel/usb.rs+12−8
@@ -36,12 +36,12 @@ pub struct Adapter<T: Driver>(T); · 35 unmodified lines
36 36
37// SAFETY:37// SAFETY:
38// - `bindings::usb_driver` is a C type declared as `repr(C)`.38// - `bindings::usb_driver` is a C type declared as `repr(C)`.
39// - `T` is the type of the driver's device private data.39// - `T::Data` is the type of the driver's device private data.
40// - `struct usb_driver` embeds a `struct device_driver`.40// - `struct usb_driver` embeds a `struct device_driver`.
41// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.41// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
42unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {42unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
43 type DriverType = bindings::usb_driver;43 type DriverType = bindings::usb_driver;
44 type DriverData = T;44 type DriverData<'bound> = T::Data;
45 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);45 const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
46}46}
47 47
@@ -109,8 +109,8 @@ impl<T: Driver> Adapter<T> { · 61 unmodified lines
109 109
110 // SAFETY: `disconnect_callback` is only ever called after a successful call to110 // SAFETY: `disconnect_callback` is only ever called after a successful call to
111 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called111 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
112 // and stored a `Pin<KBox<T>>`.112 // and stored a `Pin<KBox<T::Data>>`.
113 let data = unsafe { dev.drvdata_borrow::<T>() };113 let data = unsafe { dev.drvdata_borrow::<T::Data>() };
114 114
115 T::disconnect(intf, data);115 T::disconnect(intf, data);
116 }116 }
@@ -287,23 +287,27 @@ macro_rules! usb_device_table { · 170 unmodified lines
287///287///
288/// impl usb::Driver for MyDriver {288/// impl usb::Driver for MyDriver {
289/// type IdInfo = ();289/// type IdInfo = ();
290/// type Data = Self;
290/// const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;291/// const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;
291///292///
292/// fn probe(293/// fn probe(
293/// _interface: &usb::Interface<Core>,294/// _interface: &usb::Interface<Core>,
294/// _id: &usb::DeviceId,295/// _id: &usb::DeviceId,
295/// _info: &Self::IdInfo,296/// _info: &Self::IdInfo,
296/// ) -> impl PinInit<Self, Error> {297/// ) -> impl PinInit<Self::Data, Error> {
297/// Err(ENODEV)298/// Err(ENODEV)
298/// }299/// }
299///300///
300/// fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self>) {}301/// fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self::Data>) {}
301/// }302/// }
302///```303///```
303pub trait Driver {304pub trait Driver {
304 /// The type holding information about each one of the device ids supported by the driver.305 /// The type holding information about each one of the device ids supported by the driver.
305 type IdInfo: 'static;306 type IdInfo: 'static;
306 307
308 /// The type of the driver's bus device private data.
309 type Data: Send;
310
307 /// The table of device ids supported by the driver.311 /// The table of device ids supported by the driver.
308 const ID_TABLE: IdTable<Self::IdInfo>;312 const ID_TABLE: IdTable<Self::IdInfo>;
309 313
@@ -315,12 +319,12 @@ pub trait Driver { · 5 unmodified lines
315 interface: &Interface<device::Core>,319 interface: &Interface<device::Core>,
316 id: &DeviceId,320 id: &DeviceId,
317 id_info: &Self::IdInfo,321 id_info: &Self::IdInfo,
318 ) -> impl PinInit<Self, Error>;322 ) -> impl PinInit<Self::Data, Error>;
319 323
320 /// USB driver disconnect.324 /// USB driver disconnect.
321 ///325 ///
322 /// Called when the USB interface is about to be unbound from this driver.326 /// Called when the USB interface is about to be unbound from this driver.
323 fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self>);327 fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self::Data>);
324}328}
325 329
326/// A USB interface.330/// A USB interface.
samples/rust/rust_debugfs.rs+1−0
@@ -117,6 +117,7 @@ kernel::acpi_device_table!( · 116 unmodified lines
117 117
118impl platform::Driver for RustDebugFs {118impl platform::Driver for RustDebugFs {
119 type IdInfo = ();119 type IdInfo = ();
120 type Data = Self;
120 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;121 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
121 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);122 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
122 123
samples/rust/rust_dma.rs+1−0
@@ -58,6 +58,7 @@ kernel::pci_device_table!( · 57 unmodified lines
58 58
59impl pci::Driver for DmaSampleDriver {59impl pci::Driver for DmaSampleDriver {
60 type IdInfo = ();60 type IdInfo = ();
61 type Data = Self;
61 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;62 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
62 63
63 fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {64 fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
samples/rust/rust_driver_auxiliary.rs+2−0
@@ -31,6 +31,7 @@ kernel::auxiliary_device_table!( · 30 unmodified lines
31 31
32impl auxiliary::Driver for AuxiliaryDriver {32impl auxiliary::Driver for AuxiliaryDriver {
33 type IdInfo = ();33 type IdInfo = ();
34 type Data = Self;
34 35
35 const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;36 const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
36 37
@@ -65,6 +66,7 @@ kernel::pci_device_table!( · 28 unmodified lines
65 66
66impl pci::Driver for ParentDriver {67impl pci::Driver for ParentDriver {
67 type IdInfo = ();68 type IdInfo = ();
69 type Data = Self;
68 70
69 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;71 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
70 72
samples/rust/rust_driver_i2c.rs+1−0
@@ -35,6 +35,7 @@ kernel::of_device_table! { · 34 unmodified lines
35 35
36impl i2c::Driver for SampleDriver {36impl i2c::Driver for SampleDriver {
37 type IdInfo = u32;37 type IdInfo = u32;
38 type Data = Self;
38 39
39 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);40 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
40 const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);41 const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);
samples/rust/rust_driver_pci.rs+1−0
@@ -140,6 +140,7 @@ impl SampleDriver { · 139 unmodified lines
140 140
141impl pci::Driver for SampleDriver {141impl pci::Driver for SampleDriver {
142 type IdInfo = TestIndex;142 type IdInfo = TestIndex;
143 type Data = Self;
143 144
144 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;145 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
145 146
samples/rust/rust_driver_platform.rs+1−0
@@ -101,6 +101,7 @@ kernel::acpi_device_table!( · 100 unmodified lines
101 101
102impl platform::Driver for SampleDriver {102impl platform::Driver for SampleDriver {
103 type IdInfo = Info;103 type IdInfo = Info;
104 type Data = Self;
104 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);105 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
105 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);106 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
106 107
samples/rust/rust_driver_usb.rs+1−0
@@ -26,6 +26,7 @@ kernel::usb_device_table!( · 25 unmodified lines
26 26
27impl usb::Driver for SampleDriver {27impl usb::Driver for SampleDriver {
28 type IdInfo = ();28 type IdInfo = ();
29 type Data = Self;
29 const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;30 const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;
30 31
31 fn probe(32 fn probe(
samples/rust/rust_i2c_client.rs+1−0
@@ -106,6 +106,7 @@ const BOARD_INFO: i2c::I2cBoardInfo = · 105 unmodified lines
106 106
107impl platform::Driver for SampleDriver {107impl platform::Driver for SampleDriver {
108 type IdInfo = ();108 type IdInfo = ();
109 type Data = Self;
109 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);110 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
110 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);111 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
111 112
samples/rust/rust_soc.rs+1−0
@@ -37,6 +37,7 @@ kernel::acpi_device_table!( · 36 unmodified lines
37 37
38impl platform::Driver for SampleSocDriver {38impl platform::Driver for SampleSocDriver {
39 type IdInfo = ();39 type IdInfo = ();
40 type Data = Self;
40 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);41 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
41 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);42 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
42 43