public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: Dirk Behme <dirk.behme@gmail.com>
To: Zijing Zhang <zijing.zhang@ry.rs>,
	dakr@kernel.org, linux-pci@vger.kernel.org,
	rust-for-linux@vger.kernel.org
Cc: bhelgaas@google.com, kwilczynski@kernel.org, ojeda@kernel.org,
	gary@garyguo.net
Subject: Re: [PATCH v3 1/2] rust: pci: add capability lookup helpers
Date: Sun, 1 Feb 2026 07:24:50 +0100	[thread overview]
Message-ID: <d8549758-e2ac-4d5a-8231-790498556de3@gmail.com> (raw)
In-Reply-To: <20260131151749.1444030-2-zijing.zhang@ry.rs>

Hi Zijing,

some quite minor stylistic nits below:

On 31.01.26 16:17, Zijing Zhang wrote:
> Add thin wrappers around pci_find_capability() and
> pci_find_ext_capability().

pci_find_capability() -> `pci_find_capability()`

Same for the other cases and the 2nd commit message.

> The helpers return the capability offset in config space, or None if the
> capability is not present.
> 
> Introduce CapabilityId and ExtendedCapabilityId newtypes so drivers can use
> named constants without importing raw bindgen constants, while still
> allowing uncommon IDs via from_raw().
> 
> Signed-off-by: Zijing Zhang <zijing.zhang@ry.rs>
> ---
>  rust/kernel/pci.rs | 149 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
> 
> diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
> index 82e128431f08..213ff856f538 100644
> --- a/rust/kernel/pci.rs
> +++ b/rust/kernel/pci.rs
> @@ -41,6 +41,118 @@
>      Vendor, //
>  };
>  pub use self::io::Bar;
> +
> +/// A standard PCI capability ID.
> +///
> +/// This is a thin wrapper around the underlying numeric capability ID.
> +#[repr(transparent)]
> +#[derive(Clone, Copy, Debug, Eq, PartialEq)]
> +pub struct CapabilityId(u8);
> +
> +impl CapabilityId {
> +    /// Creates a [`CapabilityId`] from a raw value.
> +    #[inline]
> +    pub const fn from_raw(id: u8) -> Self {
> +        Self(id)
> +    }
> +
> +    /// Returns the raw value.
> +    #[inline]
> +    pub const fn as_raw(self) -> u8 {
> +        self.0
> +    }
> +
> +    /// Power Management.
> +    pub const PM: Self = Self(bindings::PCI_CAP_ID_PM as u8);
> +    /// Accelerated Graphics Port.
> +    pub const AGP: Self = Self(bindings::PCI_CAP_ID_AGP as u8);
> +    /// Vital Product Data.
> +    pub const VPD: Self = Self(bindings::PCI_CAP_ID_VPD as u8);
> +    /// Slot Identification.
> +    pub const SLOTID: Self = Self(bindings::PCI_CAP_ID_SLOTID as u8);
> +    /// Message Signalled Interrupts.
> +    pub const MSI: Self = Self(bindings::PCI_CAP_ID_MSI as u8);
> +    /// CompactPCI HotSwap.
> +    pub const CHSWP: Self = Self(bindings::PCI_CAP_ID_CHSWP as u8);
> +    /// PCI-X.
> +    pub const PCIX: Self = Self(bindings::PCI_CAP_ID_PCIX as u8);
> +    /// HyperTransport.
> +    pub const HT: Self = Self(bindings::PCI_CAP_ID_HT as u8);
> +    /// Vendor-Specific.
> +    pub const VNDR: Self = Self(bindings::PCI_CAP_ID_VNDR as u8);
> +    /// Debug port.
> +    pub const DBG: Self = Self(bindings::PCI_CAP_ID_DBG as u8);
> +    /// CompactPCI Central Resource Control.
> +    pub const CCRC: Self = Self(bindings::PCI_CAP_ID_CCRC as u8);
> +    /// PCI Standard Hot-Plug Controller.
> +    pub const SHPC: Self = Self(bindings::PCI_CAP_ID_SHPC as u8);
> +    /// Bridge subsystem vendor/device ID.
> +    pub const SSVID: Self = Self(bindings::PCI_CAP_ID_SSVID as u8);
> +    /// AGP 8x.
> +    pub const AGP3: Self = Self(bindings::PCI_CAP_ID_AGP3 as u8);
> +    /// Secure Device.
> +    pub const SECDEV: Self = Self(bindings::PCI_CAP_ID_SECDEV as u8);
> +    /// PCI Express.
> +    pub const EXP: Self = Self(bindings::PCI_CAP_ID_EXP as u8);
> +    /// MSI-X.
> +    pub const MSIX: Self = Self(bindings::PCI_CAP_ID_MSIX as u8);
> +    /// Serial ATA Data/Index Configuration.
> +    pub const SATA: Self = Self(bindings::PCI_CAP_ID_SATA as u8);
> +    /// PCI Advanced Features.
> +    pub const AF: Self = Self(bindings::PCI_CAP_ID_AF as u8);
> +    /// PCI Enhanced Allocation.
> +    pub const EA: Self = Self(bindings::PCI_CAP_ID_EA as u8);
> +}
> +
> +/// A PCIe extended capability ID.
> +///
> +/// This is a thin wrapper around the underlying numeric capability ID.
> +#[repr(transparent)]
> +#[derive(Clone, Copy, Debug, Eq, PartialEq)]
> +pub struct ExtendedCapabilityId(u16);
> +
> +impl ExtendedCapabilityId {
> +    /// Creates an [`ExtendedCapabilityId`] from a raw value.
> +    #[inline]
> +    pub const fn from_raw(id: u16) -> Self {
> +        Self(id)
> +    }
> +
> +    /// Returns the raw value.
> +    #[inline]
> +    pub const fn as_raw(self) -> u16 {
> +        self.0
> +    }
> +
> +    /// Advanced Error Reporting.
> +    pub const ERR: Self = Self(bindings::PCI_EXT_CAP_ID_ERR as u16);
> +    /// Virtual Channel.
> +    pub const VC: Self = Self(bindings::PCI_EXT_CAP_ID_VC as u16);
> +    /// Device Serial Number.
> +    pub const DSN: Self = Self(bindings::PCI_EXT_CAP_ID_DSN as u16);
> +    /// Vendor-Specific Extended Capability.
> +    pub const VNDR: Self = Self(bindings::PCI_EXT_CAP_ID_VNDR as u16);
> +    /// Access Control Services.
> +    pub const ACS: Self = Self(bindings::PCI_EXT_CAP_ID_ACS as u16);
> +    /// Alternate Routing-ID Interpretation.
> +    pub const ARI: Self = Self(bindings::PCI_EXT_CAP_ID_ARI as u16);
> +    /// Address Translation Services.
> +    pub const ATS: Self = Self(bindings::PCI_EXT_CAP_ID_ATS as u16);
> +    /// Single Root I/O Virtualization.
> +    pub const SRIOV: Self = Self(bindings::PCI_EXT_CAP_ID_SRIOV as u16);
> +    /// Resizable BAR.
> +    pub const REBAR: Self = Self(bindings::PCI_EXT_CAP_ID_REBAR as u16);
> +    /// Latency Tolerance Reporting.
> +    pub const LTR: Self = Self(bindings::PCI_EXT_CAP_ID_LTR as u16);
> +    /// Downstream Port Containment.
> +    pub const DPC: Self = Self(bindings::PCI_EXT_CAP_ID_DPC as u16);
> +    /// L1 PM Substates.
> +    pub const L1SS: Self = Self(bindings::PCI_EXT_CAP_ID_L1SS as u16);
> +    /// Precision Time Measurement.
> +    pub const PTM: Self = Self(bindings::PCI_EXT_CAP_ID_PTM as u16);
> +    /// Designated Vendor-Specific Extended Capability.
> +    pub const DVSEC: Self = Self(bindings::PCI_EXT_CAP_ID_DVSEC as u16);
> +}

Missing empty line before `pub use self::irq` below?

>  pub use self::irq::{
>      IrqType,
>      IrqTypes,
> @@ -427,6 +539,43 @@ pub fn pci_class(&self) -> Class {
>          // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
>          Class::from_raw(unsafe { (*self.as_raw()).class })
>      }
> +
> +    /// Finds a PCI capability by ID and returns its config-space offset.
> +    ///
> +    /// Returns `None` if the capability is not present.
> +    ///
> +    /// This is a thin wrapper around `pci_find_capability()`.
> +    #[inline]
> +    pub fn find_capability(&self, id: CapabilityId) -> Option<u8> {

Depending on the future use of this function (and
`find_ext_capability()` below) would it be an option to introduce a
type for the returned u8/u16 offset?

> +        // SAFETY: By its type invariant `self.as_raw` is always a valid pointer to a
> +        // `struct pci_dev`.
> +        let offset = unsafe { bindings::pci_find_capability(self.as_raw(), id.as_raw().into()) };
> +
> +        if offset == 0 {
> +            None
> +        } else {
> +            Some(offset)
> +        }

In

https://lore.kernel.org/rust-for-linux/CANiq72kiscT5euAUjcSzvxMzM9Hdj8aQGeUN_pVF-vHf3DhBuQ@mail.gmail.com/

it was proposed to use the style

if offset == 0 {
    return None;
}

Some(offset)


Best regards

Dirk


> +    }
> +
> +    /// Finds an extended capability by ID and returns its config-space offset.
> +    ///
> +    /// Returns `None` if the capability is not present.
> +    ///
> +    /// This is a thin wrapper around `pci_find_ext_capability()`.
> +    #[inline]
> +    pub fn find_ext_capability(&self, id: ExtendedCapabilityId) -> Option<u16> {
> +        // SAFETY: By its type invariant `self.as_raw` is always a valid pointer to a
> +        // `struct pci_dev`.
> +        let offset =
> +            unsafe { bindings::pci_find_ext_capability(self.as_raw(), id.as_raw().into()) };
> +
> +        if offset == 0 {
> +            None
> +        } else {
> +            Some(offset)
> +        }
> +    }
>  }
>  
>  impl Device<device::Core> {


  reply	other threads:[~2026-02-01  6:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-31  4:01 [PATCH 0/2] rust: pci: add capability lookup helpers Zijing Zhang
2026-01-31  4:01 ` [PATCH 1/2] " Zijing Zhang
2026-01-31  4:02 ` [PATCH 2/2] samples: rust: pci: exercise capability lookup Zijing Zhang
2026-01-31  9:17   ` kernel test robot
2026-01-31 13:34   ` Dirk Behme
2026-01-31 14:22     ` Zijing Zhang
2026-01-31  9:51 ` [PATCH v2 0/2] rust: pci: add capability lookup helpers Zijing Zhang
2026-01-31  9:51   ` [PATCH v2 1/2] " Zijing Zhang
2026-01-31  9:51   ` [PATCH v2 2/2] samples: rust: pci: exercise capability lookup Zijing Zhang
2026-01-31 15:17 ` [PATCH v3 0/2] rust: pci: add capability lookup helpers Zijing Zhang
2026-01-31 15:17   ` [PATCH v3 1/2] " Zijing Zhang
2026-02-01  6:24     ` Dirk Behme [this message]
2026-01-31 15:17   ` [PATCH v3 2/2] samples: rust: pci: exercise capability lookup Zijing Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d8549758-e2ac-4d5a-8231-790498556de3@gmail.com \
    --to=dirk.behme@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=kwilczynski@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=zijing.zhang@ry.rs \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox