Re: [PATCH v2 04/15] PCI: Add pci_find_vsec_capability() to find a specific VSEC

From: Lukas Wunner
Date: Tue Feb 02 2021 - 13:12:40 EST


On Tue, Feb 02, 2021 at 01:40:18PM +0100, Gustavo Pimentel wrote:
> /**
> + * pci_find_vsec_capability - Find a vendor-specific extended capability
> + * @dev: PCI device to query
> + * @cap: vendor-specific capability ID code
> + *
> + * Returns the address of the vendor-specific structure that matches the
> + * requested capability ID code within the device's PCI configuration space
> + * or 0 if it does not find a match.
> + */
> +u16 pci_find_vsec_capability(struct pci_dev *dev, int vsec_cap_id)
> +{

As the name implies, the capability is "vendor-specific", so it is perfectly
possible that two vendors use the same VSEC ID for different things.

To make sure you're looking for the right capability, you need to pass
a u16 vendor into this function and bail out if dev->vendor is different.


> + u16 vsec;
> + u32 header;
> +
> + vsec = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VNDR);
> + while (vsec) {
> + if (pci_read_config_dword(dev, vsec + PCI_VSEC_HDR,
> + &header) == PCIBIOS_SUCCESSFUL &&
> + PCI_VSEC_CAP_ID(header) == vsec_cap_id)
> + return vsec;
> +
> + vsec = pci_find_next_ext_capability(dev, vsec,
> + PCI_EXT_CAP_ID_VNDR);
> + }

FWIW, a more succinct implementation would be:

while ((vsec = pci_find_next_ext_capability(...))) { ... }

See set_pcie_thunderbolt() in drivers/pci/probe.c for an example.
Please consider refactoring that function to use your new helper.

Thanks,

Lukas