196609a19SDanilo Krummrich // SPDX-License-Identifier: GPL-2.0 296609a19SDanilo Krummrich 396609a19SDanilo Krummrich //! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`). 496609a19SDanilo Krummrich //! 596609a19SDanilo Krummrich //! To make this driver probe, QEMU must be run with `-device pci-testdev`. 696609a19SDanilo Krummrich 796609a19SDanilo Krummrich use kernel::{ 86fc4b5ebSTamir Duberstein auxiliary, 96506b44eSDanilo Krummrich device::{ 106506b44eSDanilo Krummrich Bound, 116506b44eSDanilo Krummrich Core, // 126506b44eSDanilo Krummrich }, 13b0b7301bSDanilo Krummrich devres::Devres, 14b0b7301bSDanilo Krummrich driver, 15b0b7301bSDanilo Krummrich pci, 16b0b7301bSDanilo Krummrich prelude::*, 176506b44eSDanilo Krummrich InPlaceModule, // 1896609a19SDanilo Krummrich }; 1996609a19SDanilo Krummrich 20b0b7301bSDanilo Krummrich use core::any::TypeId; 2196609a19SDanilo Krummrich use pin_init::PinInit; 2296609a19SDanilo Krummrich 2396609a19SDanilo Krummrich const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME; 246fc4b5ebSTamir Duberstein const AUXILIARY_NAME: &CStr = c"auxiliary"; 2596609a19SDanilo Krummrich 2696609a19SDanilo Krummrich struct AuxiliaryDriver; 2796609a19SDanilo Krummrich 2896609a19SDanilo Krummrich kernel::auxiliary_device_table!( 2996609a19SDanilo Krummrich AUX_TABLE, 3096609a19SDanilo Krummrich MODULE_AUX_TABLE, 3196609a19SDanilo Krummrich <AuxiliaryDriver as auxiliary::Driver>::IdInfo, 3296609a19SDanilo Krummrich [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] 3396609a19SDanilo Krummrich ); 3496609a19SDanilo Krummrich 3596609a19SDanilo Krummrich impl auxiliary::Driver for AuxiliaryDriver { 3696609a19SDanilo Krummrich type IdInfo = (); 3796609a19SDanilo Krummrich 3896609a19SDanilo Krummrich const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE; 3996609a19SDanilo Krummrich 4002426233SDanilo Krummrich fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> { 4196609a19SDanilo Krummrich dev_info!( 42*3be458a5SGary Guo adev, 4396609a19SDanilo Krummrich "Probing auxiliary driver for auxiliary device with id={}\n", 4496609a19SDanilo Krummrich adev.id() 4596609a19SDanilo Krummrich ); 4696609a19SDanilo Krummrich 4796609a19SDanilo Krummrich ParentDriver::connect(adev)?; 4896609a19SDanilo Krummrich 4902426233SDanilo Krummrich Ok(Self) 5096609a19SDanilo Krummrich } 5196609a19SDanilo Krummrich } 5296609a19SDanilo Krummrich 53e4e679c8SDanilo Krummrich #[pin_data] 5496609a19SDanilo Krummrich struct ParentDriver { 55b0b7301bSDanilo Krummrich private: TypeId, 56e4e679c8SDanilo Krummrich #[pin] 57e4e679c8SDanilo Krummrich _reg0: Devres<auxiliary::Registration>, 58e4e679c8SDanilo Krummrich #[pin] 59e4e679c8SDanilo Krummrich _reg1: Devres<auxiliary::Registration>, 6096609a19SDanilo Krummrich } 6196609a19SDanilo Krummrich 6296609a19SDanilo Krummrich kernel::pci_device_table!( 6396609a19SDanilo Krummrich PCI_TABLE, 6496609a19SDanilo Krummrich MODULE_PCI_TABLE, 6596609a19SDanilo Krummrich <ParentDriver as pci::Driver>::IdInfo, 661b8ac376SJohn Hubbard [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())] 6796609a19SDanilo Krummrich ); 6896609a19SDanilo Krummrich 6996609a19SDanilo Krummrich impl pci::Driver for ParentDriver { 7096609a19SDanilo Krummrich type IdInfo = (); 7196609a19SDanilo Krummrich 7296609a19SDanilo Krummrich const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 7396609a19SDanilo Krummrich 7402426233SDanilo Krummrich fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> { 75e4e679c8SDanilo Krummrich try_pin_init!(Self { 76b0b7301bSDanilo Krummrich private: TypeId::of::<Self>(), 77e4e679c8SDanilo Krummrich _reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME), 78e4e679c8SDanilo Krummrich _reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME), 7902426233SDanilo Krummrich }) 8096609a19SDanilo Krummrich } 8196609a19SDanilo Krummrich } 8296609a19SDanilo Krummrich 8396609a19SDanilo Krummrich impl ParentDriver { 84b0b7301bSDanilo Krummrich fn connect(adev: &auxiliary::Device<Bound>) -> Result { 85710ac546SDanilo Krummrich let dev = adev.parent(); 86b0b7301bSDanilo Krummrich let pdev: &pci::Device<Bound> = dev.try_into()?; 87b0b7301bSDanilo Krummrich let drvdata = dev.drvdata::<Self>()?; 8896609a19SDanilo Krummrich 8996609a19SDanilo Krummrich dev_info!( 90710ac546SDanilo Krummrich dev, 911b8ac376SJohn Hubbard "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", 9296609a19SDanilo Krummrich adev.id(), 93710ac546SDanilo Krummrich pdev.vendor_id(), 9496609a19SDanilo Krummrich pdev.device_id() 9596609a19SDanilo Krummrich ); 9696609a19SDanilo Krummrich 97b0b7301bSDanilo Krummrich dev_info!( 98b0b7301bSDanilo Krummrich dev, 99b0b7301bSDanilo Krummrich "We have access to the private data of {:?}.\n", 100b0b7301bSDanilo Krummrich drvdata.private 101b0b7301bSDanilo Krummrich ); 102b0b7301bSDanilo Krummrich 10396609a19SDanilo Krummrich Ok(()) 10496609a19SDanilo Krummrich } 10596609a19SDanilo Krummrich } 10696609a19SDanilo Krummrich 10796609a19SDanilo Krummrich #[pin_data] 10896609a19SDanilo Krummrich struct SampleModule { 10996609a19SDanilo Krummrich #[pin] 11096609a19SDanilo Krummrich _pci_driver: driver::Registration<pci::Adapter<ParentDriver>>, 11196609a19SDanilo Krummrich #[pin] 11296609a19SDanilo Krummrich _aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>, 11396609a19SDanilo Krummrich } 11496609a19SDanilo Krummrich 11596609a19SDanilo Krummrich impl InPlaceModule for SampleModule { 11696609a19SDanilo Krummrich fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> { 11796609a19SDanilo Krummrich try_pin_init!(Self { 11896609a19SDanilo Krummrich _pci_driver <- driver::Registration::new(MODULE_NAME, module), 11996609a19SDanilo Krummrich _aux_driver <- driver::Registration::new(MODULE_NAME, module), 12096609a19SDanilo Krummrich }) 12196609a19SDanilo Krummrich } 12296609a19SDanilo Krummrich } 12396609a19SDanilo Krummrich 12496609a19SDanilo Krummrich module! { 12596609a19SDanilo Krummrich type: SampleModule, 12696609a19SDanilo Krummrich name: "rust_driver_auxiliary", 127bfb9e46bSGuilherme Giacomo Simoes authors: ["Danilo Krummrich"], 12896609a19SDanilo Krummrich description: "Rust auxiliary driver", 12996609a19SDanilo Krummrich license: "GPL v2", 13096609a19SDanilo Krummrich } 131