Terry Bowman wrote: > CXL and AER drivers need the ability to identify CXL devices and CXL port > devices. > > First, add set_pcie_cxl() with logic checking for CXL Flexbus DVSEC > presence. The CXL Flexbus DVSEC presence is used because it is required > for all the CXL PCIe devices.[1] > > Add boolean 'struct pci_dev::is_cxl' with the purpose to cache the CXL > Flexbus presence. > > Add pcie_is_cxl() as a macro to return 'struct pci_dev::is_cxl'. > > Add pcie_is_cxl_port() to check if a device is a CXL Root Port, CXL > Upstream Switch Port, or CXL Downstream Switch Port. Also, verify the > CXL Extensions DVSEC for Ports is present.[1] > > [1] CXL 3.1 Spec, 8.1.1 PCIe Designated Vendor-Specific Extended > Capability (DVSEC) ID Assignment, Table 8-2 > > Signed-off-by: Terry Bowman <terry.bowman@xxxxxxx> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > Reviewed-by: Dave Jiang <dave.jiang@xxxxxxxxx> > Reviewed-by: Fan Ni <fan.ni@xxxxxxxxxxx> > --- > drivers/pci/pci.c | 13 +++++++++++++ > drivers/pci/probe.c | 10 ++++++++++ > include/linux/pci.h | 4 ++++ > include/uapi/linux/pci_regs.h | 3 ++- > 4 files changed, 29 insertions(+), 1 deletion(-) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 661f98c6c63a..9319c62e3488 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -5036,10 +5036,23 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe) > > static u16 cxl_port_dvsec(struct pci_dev *dev) > { > + if (!pcie_is_cxl(dev)) > + return 0; > + > return pci_find_dvsec_capability(dev, PCI_VENDOR_ID_CXL, > PCI_DVSEC_CXL_PORT); > } > > +bool pcie_is_cxl_port(struct pci_dev *dev) > +{ > + if ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && > + (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) && > + (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)) > + return false; > + > + return cxl_port_dvsec(dev); Returning bool from a function which returns u16 is odd and I don't think it should be coded this way. I don't think it is wrong right now but this really ought to code the pcie_is_cxl() here and leave cxl_port_dvsec() alone. Calling cxl_port_dvsec(), checking for if the dvsec exists, and returning bool. > +} > + [snip] > diff --git a/include/linux/pci.h b/include/linux/pci.h > index e2e36f11205c..08350302b3e9 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -452,6 +452,7 @@ struct pci_dev { > unsigned int is_hotplug_bridge:1; > unsigned int shpc_managed:1; /* SHPC owned by shpchp */ > unsigned int is_thunderbolt:1; /* Thunderbolt controller */ > + unsigned int is_cxl:1; /* Compute Express Link (CXL) */ > /* > * Devices marked being untrusted are the ones that can potentially > * execute DMA attacks and similar. They are typically connected > @@ -739,6 +740,9 @@ static inline bool pci_is_vga(struct pci_dev *pdev) > return false; > } > > +#define pcie_is_cxl(dev) (dev->is_cxl) This should be an inline function which takes struct pci_dev * for type safety. Ira [snip]