Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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