File Index
Files and directories
Sign in
FILE

rust_driver_auxiliary.rs

File preview with syntax highlighting.

linux-6.19.14/samples/rust/rust_driver_auxiliary.rs RUST
  1// SPDX-License-Identifier: GPL-2.0
  2
  3//! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`).
  4//!
  5//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
  6
  7use kernel::{
  8    auxiliary, c_str,
  9    device::{Bound, Core},
 10    devres::Devres,
 11    driver,
 12    error::Error,
 13    pci,
 14    prelude::*,
 15    InPlaceModule,
 16};
 17
 18use core::any::TypeId;
 19use pin_init::PinInit;
 20
 21const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
 22const AUXILIARY_NAME: &CStr = c_str!("auxiliary");
 23
 24struct AuxiliaryDriver;
 25
 26kernel::auxiliary_device_table!(
 27    AUX_TABLE,
 28    MODULE_AUX_TABLE,
 29    <AuxiliaryDriver as auxiliary::Driver>::IdInfo,
 30    [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())]
 31);
 32
 33impl auxiliary::Driver for AuxiliaryDriver {
 34    type IdInfo = ();
 35
 36    const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
 37
 38    fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
 39        dev_info!(
 40            adev.as_ref(),
 41            "Probing auxiliary driver for auxiliary device with id={}\n",
 42            adev.id()
 43        );
 44
 45        ParentDriver::connect(adev)?;
 46
 47        Ok(Self)
 48    }
 49}
 50
 51#[pin_data]
 52struct ParentDriver {
 53    private: TypeId,
 54    #[pin]
 55    _reg0: Devres<auxiliary::Registration>,
 56    #[pin]
 57    _reg1: Devres<auxiliary::Registration>,
 58}
 59
 60kernel::pci_device_table!(
 61    PCI_TABLE,
 62    MODULE_PCI_TABLE,
 63    <ParentDriver as pci::Driver>::IdInfo,
 64    [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())]
 65);
 66
 67impl pci::Driver for ParentDriver {
 68    type IdInfo = ();
 69
 70    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
 71
 72    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
 73        try_pin_init!(Self {
 74            private: TypeId::of::<Self>(),
 75            _reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME),
 76            _reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME),
 77        })
 78    }
 79}
 80
 81impl ParentDriver {
 82    fn connect(adev: &auxiliary::Device<Bound>) -> Result {
 83        let dev = adev.parent();
 84        let pdev: &pci::Device<Bound> = dev.try_into()?;
 85        let drvdata = dev.drvdata::<Self>()?;
 86
 87        dev_info!(
 88            dev,
 89            "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n",
 90            adev.id(),
 91            pdev.vendor_id(),
 92            pdev.device_id()
 93        );
 94
 95        dev_info!(
 96            dev,
 97            "We have access to the private data of {:?}.\n",
 98            drvdata.private
 99        );
100
101        Ok(())
102    }
103}
104
105#[pin_data]
106struct SampleModule {
107    #[pin]
108    _pci_driver: driver::Registration<pci::Adapter<ParentDriver>>,
109    #[pin]
110    _aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>,
111}
112
113impl InPlaceModule for SampleModule {
114    fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
115        try_pin_init!(Self {
116            _pci_driver <- driver::Registration::new(MODULE_NAME, module),
117            _aux_driver <- driver::Registration::new(MODULE_NAME, module),
118        })
119    }
120}
121
122module! {
123    type: SampleModule,
124    name: "rust_driver_auxiliary",
125    authors: ["Danilo Krummrich"],
126    description: "Rust auxiliary driver",
127    license: "GPL v2",
128}
~/ Read-only file preview.