On Sun, Jun 08, 2025 at 07:51:11PM -0300, Daniel Almeida wrote: > These accessors can be used to retrieve a irq::Registration or a > irq::ThreadedRegistration from a pci device. > > These accessors ensure that only valid IRQ lines can ever be registered. > > Signed-off-by: Daniel Almeida <daniel.almeida@xxxxxxxxxxxxx> > --- > rust/kernel/pci.rs | 35 +++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs > index 8435f8132e38129ccc3495e7c4d3237fcaa97ad9..c690fa1c739c937324e902e61e68df238dbd733b 100644 > --- a/rust/kernel/pci.rs > +++ b/rust/kernel/pci.rs > @@ -395,6 +395,32 @@ pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> { > } > } > > +macro_rules! gen_irq_accessor { > + ($(#[$meta:meta])* $fn_name:ident, $reg_type:ident, $handler_trait:ident) => { > + $(#[$meta])* > + pub fn $fn_name<T: crate::irq::$handler_trait + 'static>( > + &self, > + index: u32, > + flags: crate::irq::flags::Flags, > + name: &'static crate::str::CStr, > + handler: T, > + ) -> Result<impl PinInit<crate::irq::$reg_type<T>, crate::error::Error> + '_> { > + // SAFETY: `self.as_raw` returns a valid pointer to a `struct pci_dev`. > + let irq = unsafe { crate::bindings::pci_irq_vector(self.as_raw(), index) }; > + if irq < 0 { > + return Err(crate::error::Error::from_errno(irq)); > + } > + Ok(crate::irq::$reg_type::<T>::register( > + self.as_ref(), > + irq as u32, > + flags, > + name, > + handler, > + )) > + } > + }; > +} Given that we only have two invocations below, please implement them in-place. I don't think it's worth having the macro indirection. > impl Device<device::Bound> { > /// Mapps an entire PCI-BAR after performing a region-request on it. I/O operation bound checks > /// can be performed on compile time for offsets (plus the requested type size) < SIZE. > @@ -413,6 +439,15 @@ pub fn iomap_region_sized<const SIZE: usize>( > pub fn iomap_region(&self, bar: u32, name: &CStr) -> Result<Devres<Bar>> { > self.iomap_region_sized::<0>(bar, name) > } > + > + gen_irq_accessor!( > + /// Returns a [`kernel::irq::Registration`] for the IRQ vector at the given index. > + irq_by_index, Registration, Handler > + ); > + gen_irq_accessor!( > + /// Returns a [`kernel::irq::ThreadedRegistration`] for the IRQ vector at the given index. > + threaded_irq_by_index, ThreadedRegistration, ThreadedHandler > + ); > } > > impl Device<device::Core> { > > -- > 2.49.0 >