On Wed Aug 27, 2025 at 8:12 AM JST, John Hubbard wrote: > This allows callers to write Vendor::SOME_COMPANY instead of > bindings::PCI_VENDOR_ID_SOME_COMPANY. > > New APIs: > Vendor::SOME_COMPANY > Vendor::from_raw() -- Only accessible from the pci (parent) module. > Vendor::as_raw() > Vendor: fmt::Display for Vendor > > Cc: Danilo Krummrich <dakr@xxxxxxxxxx> > Cc: Alexandre Courbot <acourbot@xxxxxxxxxx> > Cc: Elle Rhumsaa <elle@xxxxxxxxxxxxxxxxxxx> > Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx> > --- > rust/kernel/pci.rs | 2 +- > rust/kernel/pci/id.rs | 349 +++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 349 insertions(+), 2 deletions(-) > > diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs > index 212c4a6834fb..f15cfd0e76d9 100644 > --- a/rust/kernel/pci.rs > +++ b/rust/kernel/pci.rs > @@ -25,7 +25,7 @@ > > mod id; > > -pub use self::id::{Class, ClassMask}; > +pub use self::id::{Class, ClassMask, Vendor}; > > /// An adapter for the registration of PCI drivers. > pub struct Adapter<T: Driver>(T); > diff --git a/rust/kernel/pci/id.rs b/rust/kernel/pci/id.rs > index 55d9cdcc6658..4b0ad8d4edc6 100644 > --- a/rust/kernel/pci/id.rs > +++ b/rust/kernel/pci/id.rs > @@ -2,7 +2,7 @@ > > //! PCI device identifiers and related types. > //! > -//! This module contains PCI class codes and supporting types. > +//! This module contains PCI class codes, Vendor IDs, and supporting types. > > use crate::{bindings, error::code::EINVAL, error::Error, prelude::*}; > use core::fmt; > @@ -109,6 +109,69 @@ fn try_from(value: u32) -> Result<Self, Self::Error> { > } > } > > +/// PCI vendor IDs. > +/// > +/// Each entry contains the 16-bit PCI vendor ID as assigned by the PCI SIG. > +/// > +/// # Examples > +/// > +/// ``` > +/// # use kernel::{device::Core, pci::{self, Vendor}, prelude::*}; > +/// fn log_device_info(pdev: &pci::Device<Core>) -> Result<()> { > +/// // Compare raw vendor ID with known vendor constant > +/// let vendor_id = pdev.vendor_id(); > +/// if vendor_id == Vendor::NVIDIA.as_raw() { > +/// dev_info!( > +/// pdev.as_ref(), > +/// "Found NVIDIA device: 0x{:x}\n", > +/// pdev.device_id() > +/// ); > +/// } > +/// Ok(()) > +/// } > +/// ``` > +#[derive(Debug, Clone, Copy, PartialEq, Eq)] > +#[repr(transparent)] > +pub struct Vendor(u16); > + > +macro_rules! define_all_pci_vendors { > + ( > + $($variant:ident = $binding:expr,)+ > + ) => { > + > + impl Vendor { Why the blank line here? (same for the `define_all_pci_classes` in the previous patch). > + $( > + #[allow(missing_docs)] > + pub const $variant: Self = Self($binding as u16); > + )+ > + } > + }; > +} > + > +/// Once constructed, a `Vendor` contains a valid PCI Vendor ID. > +impl Vendor { > + /// Create a Vendor from a raw 16-bit vendor ID. > + /// Only accessible from the parent pci module. > + #[expect(dead_code)] > + #[inline] > + pub(super) fn from_raw(vendor_id: u16) -> Self { > + Self(vendor_id) > + } > + > + /// Get the raw 16-bit vendor ID value. > + #[inline] > + pub const fn as_raw(self) -> u16 { > + self.0 > + } > +} > + > +impl fmt::Display for Vendor { > + #[inline] > + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { > + write!(f, "0x{:04x}", self.0) > + } > +} Possibly an exercice for a future patch, but do we want to display the vendor name if it is defined, rather than its hex code (which is more the job of `Debug`)? We could leverage the macro above to do that. The same should be doable for the PCI classes. I suspect strings for all the names already exist on the C side, in which case we would want to reuse them instead of defining new ones. Note that I don't think this needs to be done for this series - it's just a thought as I was looking at this `Display` implementation that looks more like a `Debug` one.