samples: rust: auxiliary: illustrate driver interaction
Illustrate how a parent driver of an auxiliary driver can take advantage of the device context guarantees given by the auxiliary bus and subsequently safely derive its device private data. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
@@ -5,10 +5,17 @@
|
|||||||
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
|
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
|
||||||
|
|
||||||
use kernel::{
|
use kernel::{
|
||||||
auxiliary, c_str, device::Core, devres::Devres, driver, error::Error, pci, prelude::*,
|
auxiliary, c_str,
|
||||||
|
device::{Bound, Core},
|
||||||
|
devres::Devres,
|
||||||
|
driver,
|
||||||
|
error::Error,
|
||||||
|
pci,
|
||||||
|
prelude::*,
|
||||||
InPlaceModule,
|
InPlaceModule,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use core::any::TypeId;
|
||||||
use pin_init::PinInit;
|
use pin_init::PinInit;
|
||||||
|
|
||||||
const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
|
const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
|
||||||
@@ -43,6 +50,7 @@ impl auxiliary::Driver for AuxiliaryDriver {
|
|||||||
|
|
||||||
#[pin_data]
|
#[pin_data]
|
||||||
struct ParentDriver {
|
struct ParentDriver {
|
||||||
|
private: TypeId,
|
||||||
#[pin]
|
#[pin]
|
||||||
_reg0: Devres<auxiliary::Registration>,
|
_reg0: Devres<auxiliary::Registration>,
|
||||||
#[pin]
|
#[pin]
|
||||||
@@ -63,6 +71,7 @@ impl pci::Driver for ParentDriver {
|
|||||||
|
|
||||||
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
|
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
|
||||||
try_pin_init!(Self {
|
try_pin_init!(Self {
|
||||||
|
private: TypeId::of::<Self>(),
|
||||||
_reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME),
|
_reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME),
|
||||||
_reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME),
|
_reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME),
|
||||||
})
|
})
|
||||||
@@ -70,9 +79,10 @@ impl pci::Driver for ParentDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ParentDriver {
|
impl ParentDriver {
|
||||||
fn connect(adev: &auxiliary::Device) -> Result {
|
fn connect(adev: &auxiliary::Device<Bound>) -> Result {
|
||||||
let dev = adev.parent();
|
let dev = adev.parent();
|
||||||
let pdev: &pci::Device = dev.try_into()?;
|
let pdev: &pci::Device<Bound> = dev.try_into()?;
|
||||||
|
let drvdata = dev.drvdata::<Self>()?;
|
||||||
|
|
||||||
dev_info!(
|
dev_info!(
|
||||||
dev,
|
dev,
|
||||||
@@ -82,6 +92,12 @@ impl ParentDriver {
|
|||||||
pdev.device_id()
|
pdev.device_id()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
dev_info!(
|
||||||
|
dev,
|
||||||
|
"We have access to the private data of {:?}.\n",
|
||||||
|
drvdata.private
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user