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 2296609a19SDanilo Krummrich const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME; 236fc4b5ebSTamir Duberstein const AUXILIARY_NAME: &CStr = c"auxiliary"; 2496609a19SDanilo Krummrich 2596609a19SDanilo Krummrich struct AuxiliaryDriver; 2696609a19SDanilo Krummrich 2796609a19SDanilo Krummrich kernel::auxiliary_device_table!( 2896609a19SDanilo Krummrich AUX_TABLE, 2996609a19SDanilo Krummrich MODULE_AUX_TABLE, 3096609a19SDanilo Krummrich <AuxiliaryDriver as auxiliary::Driver>::IdInfo, 3196609a19SDanilo Krummrich [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] 3296609a19SDanilo Krummrich ); 3396609a19SDanilo Krummrich 3496609a19SDanilo Krummrich impl auxiliary::Driver for AuxiliaryDriver { 3596609a19SDanilo Krummrich type IdInfo = (); 3696609a19SDanilo Krummrich 3796609a19SDanilo Krummrich const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE; 3896609a19SDanilo Krummrich 3902426233SDanilo Krummrich fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> { 4096609a19SDanilo Krummrich dev_info!( 41*3be458a5SGary Guo adev, 4296609a19SDanilo Krummrich "Probing auxiliary driver for auxiliary device with id={}\n", 4396609a19SDanilo Krummrich adev.id() 4496609a19SDanilo Krummrich ); 4596609a19SDanilo Krummrich 4696609a19SDanilo Krummrich ParentDriver::connect(adev)?; 4796609a19SDanilo Krummrich 4802426233SDanilo Krummrich Ok(Self) 4996609a19SDanilo Krummrich } 5096609a19SDanilo Krummrich } 5196609a19SDanilo Krummrich 52e4e679c8SDanilo Krummrich #[pin_data] 5396609a19SDanilo Krummrich struct ParentDriver { 54b0b7301bSDanilo Krummrich private: TypeId, 55e4e679c8SDanilo Krummrich #[pin] 56e4e679c8SDanilo Krummrich _reg0: Devres<auxiliary::Registration>, 57e4e679c8SDanilo Krummrich #[pin] 58e4e679c8SDanilo Krummrich _reg1: Devres<auxiliary::Registration>, 5996609a19SDanilo Krummrich } 6096609a19SDanilo Krummrich 6196609a19SDanilo Krummrich kernel::pci_device_table!( 6296609a19SDanilo Krummrich PCI_TABLE, 6396609a19SDanilo Krummrich MODULE_PCI_TABLE, 6496609a19SDanilo Krummrich <ParentDriver as pci::Driver>::IdInfo, 651b8ac376SJohn Hubbard [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())] 6696609a19SDanilo Krummrich ); 6796609a19SDanilo Krummrich 6896609a19SDanilo Krummrich impl pci::Driver for ParentDriver { 6996609a19SDanilo Krummrich type IdInfo = (); 7096609a19SDanilo Krummrich 7196609a19SDanilo Krummrich const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 7296609a19SDanilo Krummrich 7302426233SDanilo Krummrich fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> { 74e4e679c8SDanilo Krummrich try_pin_init!(Self { 75b0b7301bSDanilo Krummrich private: TypeId::of::<Self>(), 76e4e679c8SDanilo Krummrich _reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME), 77e4e679c8SDanilo Krummrich _reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME), 7802426233SDanilo Krummrich }) 7996609a19SDanilo Krummrich } 8096609a19SDanilo Krummrich } 8196609a19SDanilo Krummrich 8296609a19SDanilo Krummrich impl ParentDriver { 83b0b7301bSDanilo Krummrich fn connect(adev: &auxiliary::Device<Bound>) -> Result { 84710ac546SDanilo Krummrich let dev = adev.parent(); 85b0b7301bSDanilo Krummrich let pdev: &pci::Device<Bound> = dev.try_into()?; 86b0b7301bSDanilo Krummrich let drvdata = dev.drvdata::<Self>()?; 8796609a19SDanilo Krummrich 8896609a19SDanilo Krummrich dev_info!( 89710ac546SDanilo Krummrich dev, 901b8ac376SJohn Hubbard "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", 9196609a19SDanilo Krummrich adev.id(), 92710ac546SDanilo Krummrich pdev.vendor_id(), 9396609a19SDanilo Krummrich pdev.device_id() 9496609a19SDanilo Krummrich ); 9596609a19SDanilo Krummrich 96b0b7301bSDanilo Krummrich dev_info!( 97b0b7301bSDanilo Krummrich dev, 98b0b7301bSDanilo Krummrich "We have access to the private data of {:?}.\n", 99b0b7301bSDanilo Krummrich drvdata.private 100b0b7301bSDanilo Krummrich ); 101b0b7301bSDanilo Krummrich 10296609a19SDanilo Krummrich Ok(()) 10396609a19SDanilo Krummrich } 10496609a19SDanilo Krummrich } 10596609a19SDanilo Krummrich 10696609a19SDanilo Krummrich #[pin_data] 10796609a19SDanilo Krummrich struct SampleModule { 10896609a19SDanilo Krummrich #[pin] 10996609a19SDanilo Krummrich _pci_driver: driver::Registration<pci::Adapter<ParentDriver>>, 11096609a19SDanilo Krummrich #[pin] 11196609a19SDanilo Krummrich _aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>, 11296609a19SDanilo Krummrich } 11396609a19SDanilo Krummrich 11496609a19SDanilo Krummrich impl InPlaceModule for SampleModule { 11596609a19SDanilo Krummrich fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> { 11696609a19SDanilo Krummrich try_pin_init!(Self { 11796609a19SDanilo Krummrich _pci_driver <- driver::Registration::new(MODULE_NAME, module), 11896609a19SDanilo Krummrich _aux_driver <- driver::Registration::new(MODULE_NAME, module), 11996609a19SDanilo Krummrich }) 12096609a19SDanilo Krummrich } 12196609a19SDanilo Krummrich } 12296609a19SDanilo Krummrich 12396609a19SDanilo Krummrich module! { 12496609a19SDanilo Krummrich type: SampleModule, 12596609a19SDanilo Krummrich name: "rust_driver_auxiliary", 126bfb9e46bSGuilherme Giacomo Simoes authors: ["Danilo Krummrich"], 12796609a19SDanilo Krummrich description: "Rust auxiliary driver", 12896609a19SDanilo Krummrich license: "GPL v2", 12996609a19SDanilo Krummrich } 130