Path: blob/master/samples/rust/rust_driver_auxiliary.rs
48999 views
// SPDX-License-Identifier: GPL-2.012//! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`).3//!4//! To make this driver probe, QEMU must be run with `-device pci-testdev`.56use kernel::{7auxiliary, c_str,8device::{Bound, Core},9devres::Devres,10driver,11error::Error,12pci,13prelude::*,14InPlaceModule,15};1617use core::any::TypeId;18use pin_init::PinInit;1920const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;21const AUXILIARY_NAME: &CStr = c_str!("auxiliary");2223struct AuxiliaryDriver;2425kernel::auxiliary_device_table!(26AUX_TABLE,27MODULE_AUX_TABLE,28<AuxiliaryDriver as auxiliary::Driver>::IdInfo,29[(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())]30);3132impl auxiliary::Driver for AuxiliaryDriver {33type IdInfo = ();3435const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;3637fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {38dev_info!(39adev.as_ref(),40"Probing auxiliary driver for auxiliary device with id={}\n",41adev.id()42);4344ParentDriver::connect(adev)?;4546Ok(Self)47}48}4950#[pin_data]51struct ParentDriver {52private: TypeId,53#[pin]54_reg0: Devres<auxiliary::Registration>,55#[pin]56_reg1: Devres<auxiliary::Registration>,57}5859kernel::pci_device_table!(60PCI_TABLE,61MODULE_PCI_TABLE,62<ParentDriver as pci::Driver>::IdInfo,63[(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())]64);6566impl pci::Driver for ParentDriver {67type IdInfo = ();6869const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;7071fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {72try_pin_init!(Self {73private: TypeId::of::<Self>(),74_reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME),75_reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME),76})77}78}7980impl ParentDriver {81fn connect(adev: &auxiliary::Device<Bound>) -> Result {82let dev = adev.parent();83let pdev: &pci::Device<Bound> = dev.try_into()?;84let drvdata = dev.drvdata::<Self>()?;8586dev_info!(87dev,88"Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n",89adev.id(),90pdev.vendor_id(),91pdev.device_id()92);9394dev_info!(95dev,96"We have access to the private data of {:?}.\n",97drvdata.private98);99100Ok(())101}102}103104#[pin_data]105struct SampleModule {106#[pin]107_pci_driver: driver::Registration<pci::Adapter<ParentDriver>>,108#[pin]109_aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>,110}111112impl InPlaceModule for SampleModule {113fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {114try_pin_init!(Self {115_pci_driver <- driver::Registration::new(MODULE_NAME, module),116_aux_driver <- driver::Registration::new(MODULE_NAME, module),117})118}119}120121module! {122type: SampleModule,123name: "rust_driver_auxiliary",124authors: ["Danilo Krummrich"],125description: "Rust auxiliary driver",126license: "GPL v2",127}128129130