diff options
| author | Danilo Krummrich <dakr@kernel.org> | 2025-10-15 20:14:29 +0200 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2025-10-20 12:03:23 +0200 |
| commit | 651692d32c21a9165db60a9bc74600074cd4ed99 (patch) | |
| tree | 8061dcf4d3675454731e6574446e288e5f4bb6d7 | |
| parent | 340ccc973544a6e7e331729bc4944603085cafab (diff) | |
rust: pci: implement TryInto<IrqRequest<'a>> for IrqVector<'a>
Implement TryInto<IrqRequest<'a>> for IrqVector<'a> to directly convert
a pci::IrqVector into a generic IrqRequest, instead of taking the
indirection via an unrelated pci::Device method.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
| -rw-r--r-- | rust/kernel/pci.rs | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index d91ec9f008ae..c6b750047b2e 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -596,6 +596,20 @@ impl<'a> IrqVector<'a> { } } +impl<'a> TryInto<IrqRequest<'a>> for IrqVector<'a> { + type Error = Error; + + fn try_into(self) -> Result<IrqRequest<'a>> { + // SAFETY: `self.as_raw` returns a valid pointer to a `struct pci_dev`. + let irq = unsafe { bindings::pci_irq_vector(self.dev.as_raw(), self.index()) }; + if irq < 0 { + return Err(crate::error::Error::from_errno(irq)); + } + // SAFETY: `irq` is guaranteed to be a valid IRQ number for `&self`. + Ok(unsafe { IrqRequest::new(self.dev.as_ref(), irq as u32) }) + } +} + /// Represents an IRQ vector allocation for a PCI device. /// /// This type ensures that IRQ vectors are properly allocated and freed by @@ -675,31 +689,15 @@ impl Device<device::Bound> { self.iomap_region_sized::<0>(bar, name) } - /// Returns an [`IrqRequest`] for the given IRQ vector. - pub fn irq_vector(&self, vector: IrqVector<'_>) -> Result<IrqRequest<'_>> { - // Verify that the vector belongs to this device. - if !core::ptr::eq(vector.dev.as_raw(), self.as_raw()) { - return Err(EINVAL); - } - - // SAFETY: `self.as_raw` returns a valid pointer to a `struct pci_dev`. - let irq = unsafe { crate::bindings::pci_irq_vector(self.as_raw(), vector.index()) }; - if irq < 0 { - return Err(crate::error::Error::from_errno(irq)); - } - // SAFETY: `irq` is guaranteed to be a valid IRQ number for `&self`. - Ok(unsafe { IrqRequest::new(self.as_ref(), irq as u32) }) - } - /// Returns a [`kernel::irq::Registration`] for the given IRQ vector. pub fn request_irq<'a, T: crate::irq::Handler + 'static>( &'a self, - vector: IrqVector<'_>, + vector: IrqVector<'a>, flags: irq::Flags, name: &'static CStr, handler: impl PinInit<T, Error> + 'a, ) -> Result<impl PinInit<irq::Registration<T>, Error> + 'a> { - let request = self.irq_vector(vector)?; + let request = vector.try_into()?; Ok(irq::Registration::<T>::new(request, flags, name, handler)) } @@ -707,12 +705,12 @@ impl Device<device::Bound> { /// Returns a [`kernel::irq::ThreadedRegistration`] for the given IRQ vector. pub fn request_threaded_irq<'a, T: crate::irq::ThreadedHandler + 'static>( &'a self, - vector: IrqVector<'_>, + vector: IrqVector<'a>, flags: irq::Flags, name: &'static CStr, handler: impl PinInit<T, Error> + 'a, ) -> Result<impl PinInit<irq::ThreadedRegistration<T>, Error> + 'a> { - let request = self.irq_vector(vector)?; + let request = vector.try_into()?; Ok(irq::ThreadedRegistration::<T>::new( request, flags, name, handler, |
