Message ID | 20250321040358.360755-2-18255117159@163.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Krzysztof WilczyĆski |
Headers | show |
Series | Introduce generic capability search functions | expand |
Hi Hans, kernel test robot noticed the following build errors: [auto build test ERROR on a1cffe8cc8aef85f1b07c4464f0998b9785b795a] url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-Introduce-generic-capability-search-functions/20250321-120748 base: a1cffe8cc8aef85f1b07c4464f0998b9785b795a patch link: https://lore.kernel.org/r/20250321040358.360755-2-18255117159%40163.com patch subject: [v3 1/4] PCI: Introduce generic capability search functions config: arc-randconfig-002-20250321 (https://download.01.org/0day-ci/archive/20250321/202503211726.DEvDBGk8-lkp@intel.com/config) compiler: arc-linux-gcc (GCC) 11.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250321/202503211726.DEvDBGk8-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503211726.DEvDBGk8-lkp@intel.com/ All error/warnings (new ones prefixed by >>): In file included from drivers/nvme/host/nvme.h:11, from drivers/nvme/host/fc.c:13: >> include/linux/pci.h:2021:4: warning: no previous prototype for 'pci_generic_find_capability' [-Wmissing-prototypes] 2021 | u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ >> include/linux/pci.h:2024:5: warning: no previous prototype for 'pci_generic_find_ext_capability' [-Wmissing-prototypes] 2024 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- arc-linux-ld: drivers/scsi/libsas/sas_phy.o: in function `pci_generic_find_capability': >> sas_phy.c:(.text+0x148): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_phy.o: in function `pci_generic_find_ext_capability': >> sas_phy.c:(.text+0x150): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_port.o: in function `pci_generic_find_capability': sas_port.c:(.text+0x1c8): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_port.o: in function `pci_generic_find_ext_capability': sas_port.c:(.text+0x1d0): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_event.o: in function `pci_generic_find_capability': sas_event.c:(.text+0xf8): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_event.o: in function `pci_generic_find_ext_capability': sas_event.c:(.text+0x100): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_discover.o: in function `pci_generic_find_capability': sas_discover.c:(.text+0x874): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_discover.o: in function `pci_generic_find_ext_capability': sas_discover.c:(.text+0x87c): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_expander.o: in function `pci_generic_find_capability': sas_expander.c:(.text+0x2378): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_expander.o: in function `pci_generic_find_ext_capability': sas_expander.c:(.text+0x2380): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_scsi_host.o: in function `pci_generic_find_capability': sas_scsi_host.c:(.text+0x17c0): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_scsi_host.o: in function `pci_generic_find_ext_capability': sas_scsi_host.c:(.text+0x17c8): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_task.o: in function `pci_generic_find_capability': sas_task.c:(.text+0xd4): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_task.o: in function `pci_generic_find_ext_capability': sas_task.c:(.text+0xdc): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here arc-linux-ld: drivers/scsi/libsas/sas_host_smp.o: in function `pci_generic_find_capability': sas_host_smp.c:(.text+0x48): multiple definition of `pci_generic_find_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd18): first defined here arc-linux-ld: drivers/scsi/libsas/sas_host_smp.o: in function `pci_generic_find_ext_capability': sas_host_smp.c:(.text+0x50): multiple definition of `pci_generic_find_ext_capability'; drivers/scsi/libsas/sas_init.o:sas_init.c:(.text+0xd20): first defined here -- arc-linux-ld: drivers/pcmcia/cistpl.o: in function `pci_generic_find_capability': >> cistpl.c:(.text+0xfac): multiple definition of `pci_generic_find_capability'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0x1244): first defined here arc-linux-ld: drivers/pcmcia/cistpl.o: in function `pci_generic_find_ext_capability': >> cistpl.c:(.text+0xfb4): multiple definition of `pci_generic_find_ext_capability'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0x124c): first defined here
Hi Hans, kernel test robot noticed the following build warnings: [auto build test WARNING on a1cffe8cc8aef85f1b07c4464f0998b9785b795a] url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-Introduce-generic-capability-search-functions/20250321-120748 base: a1cffe8cc8aef85f1b07c4464f0998b9785b795a patch link: https://lore.kernel.org/r/20250321040358.360755-2-18255117159%40163.com patch subject: [v3 1/4] PCI: Introduce generic capability search functions config: arm-randconfig-004-20250321 (https://download.01.org/0day-ci/archive/20250321/202503211730.XKhqW2Mw-lkp@intel.com/config) compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project c2692afc0a92cd5da140dfcdfff7818a5b8ce997) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250321/202503211730.XKhqW2Mw-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503211730.XKhqW2Mw-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from arch/arm/mm/iomap.c:9: >> include/linux/pci.h:2021:4: warning: no previous prototype for function 'pci_generic_find_capability' [-Wmissing-prototypes] 2021 | u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, | ^ include/linux/pci.h:2021:1: note: declare 'static' if the function is not intended to be used outside of this translation unit 2021 | u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, | ^ | static >> include/linux/pci.h:2024:5: warning: no previous prototype for function 'pci_generic_find_ext_capability' [-Wmissing-prototypes] 2024 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^ include/linux/pci.h:2024:1: note: declare 'static' if the function is not intended to be used outside of this translation unit 2024 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^ | static 2 warnings generated. vim +/pci_generic_find_capability +2021 include/linux/pci.h 1999 2000 static inline void pci_set_master(struct pci_dev *dev) { } 2001 static inline void pci_clear_master(struct pci_dev *dev) { } 2002 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } 2003 static inline void pci_disable_device(struct pci_dev *dev) { } 2004 static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; } 2005 static inline int pci_assign_resource(struct pci_dev *dev, int i) 2006 { return -EBUSY; } 2007 static inline int __must_check __pci_register_driver(struct pci_driver *drv, 2008 struct module *owner, 2009 const char *mod_name) 2010 { return 0; } 2011 static inline int pci_register_driver(struct pci_driver *drv) 2012 { return 0; } 2013 static inline void pci_unregister_driver(struct pci_driver *drv) { } 2014 static inline u8 pci_find_capability(struct pci_dev *dev, int cap) 2015 { return 0; } 2016 static inline u8 pci_find_next_capability(struct pci_dev *dev, u8 post, int cap) 2017 { return 0; } 2018 static inline u16 pci_find_ext_capability(struct pci_dev *dev, int cap) 2019 { return 0; } 2020 typedef u32 (*pci_generic_read_cfg)(void *priv, int where, int size); > 2021 u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, 2022 u8 cap) 2023 { return 0; } > 2024 u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, 2025 u8 cap) 2026 { return 0; } 2027 static inline u64 pci_get_dsn(struct pci_dev *dev) 2028 { return 0; } 2029
Hi Hans, kernel test robot noticed the following build errors: [auto build test ERROR on a1cffe8cc8aef85f1b07c4464f0998b9785b795a] url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-Introduce-generic-capability-search-functions/20250321-120748 base: a1cffe8cc8aef85f1b07c4464f0998b9785b795a patch link: https://lore.kernel.org/r/20250321040358.360755-2-18255117159%40163.com patch subject: [v3 1/4] PCI: Introduce generic capability search functions config: arc-randconfig-001-20250321 (https://download.01.org/0day-ci/archive/20250321/202503211714.tv7E2QkK-lkp@intel.com/config) compiler: arc-linux-gcc (GCC) 13.3.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250321/202503211714.tv7E2QkK-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503211714.tv7E2QkK-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/pci/pci.c:691:5: error: conflicting types for 'pci_generic_find_ext_capability'; have 'u16(void *, u32 (*)(void *, int, int), int)' {aka 'short unsigned int(void *, unsigned int (*)(void *, int, int), int)'} 691 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pci/pci.c:18: include/linux/pci.h:1211:5: note: previous declaration of 'pci_generic_find_ext_capability' with type 'u16(void *, u32 (*)(void *, int, int), u8)' {aka 'short unsigned int(void *, unsigned int (*)(void *, int, int), unsigned char)'} 1211 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/preempt.h:10, from include/linux/spinlock.h:56, from include/linux/mmzone.h:8, from include/linux/gfp.h:7, from include/linux/slab.h:16, from include/linux/resource_ext.h:11, from include/linux/acpi.h:13, from drivers/pci/pci.c:11: drivers/pci/pci.c:696:19: error: conflicting types for 'pci_generic_find_ext_capability'; have 'u16(void *, u32 (*)(void *, int, int), int)' {aka 'short unsigned int(void *, unsigned int (*)(void *, int, int), int)'} 696 | EXPORT_SYMBOL_GPL(pci_generic_find_ext_capability); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/export.h:70:28: note: in definition of macro '__EXPORT_SYMBOL' 70 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:84:41: note: in expansion of macro '_EXPORT_SYMBOL' 84 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ drivers/pci/pci.c:696:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 696 | EXPORT_SYMBOL_GPL(pci_generic_find_ext_capability); | ^~~~~~~~~~~~~~~~~ include/linux/pci.h:1211:5: note: previous declaration of 'pci_generic_find_ext_capability' with type 'u16(void *, u32 (*)(void *, int, int), u8)' {aka 'short unsigned int(void *, unsigned int (*)(void *, int, int), unsigned char)'} 1211 | u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +691 drivers/pci/pci.c 690 > 691 u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, 692 int cap) 693 { 694 return pci_generic_find_next_ext_capability(priv, read_cfg, 0, cap); 695 } 696 EXPORT_SYMBOL_GPL(pci_generic_find_ext_capability); 697
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 869d204a70a3..d686d89d211e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -612,6 +612,89 @@ u16 pci_find_ext_capability(struct pci_dev *dev, int cap) } EXPORT_SYMBOL_GPL(pci_find_ext_capability); +/* + * These interfaces resemble the pci_find_*capability() interfaces, but these + * are for configuring host controllers, which are bridges *to* PCI devices but + * are not PCI devices themselves. + */ +static u8 __pci_generic_find_next_cap(void *priv, pci_generic_read_cfg read_cfg, + u8 cap_ptr, u8 cap) +{ + u8 cap_id, next_cap_ptr; + u16 reg; + + if (!cap_ptr) + return 0; + + reg = read_cfg(priv, cap_ptr, 2); + cap_id = (reg & 0x00ff); + + if (cap_id > PCI_CAP_ID_MAX) + return 0; + + if (cap_id == cap) + return cap_ptr; + + next_cap_ptr = (reg & 0xff00) >> 8; + return __pci_generic_find_next_cap(priv, read_cfg, next_cap_ptr, cap); +} + +u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, + u8 cap) +{ + u8 next_cap_ptr; + u16 reg; + + reg = read_cfg(priv, PCI_CAPABILITY_LIST, 2); + next_cap_ptr = (reg & 0x00ff); + + return __pci_generic_find_next_cap(priv, read_cfg, next_cap_ptr, cap); +} +EXPORT_SYMBOL_GPL(pci_generic_find_capability); + +static u16 pci_generic_find_next_ext_capability(void *priv, + pci_generic_read_cfg read_cfg, + u16 start, u8 cap) +{ + u32 header; + int ttl; + int pos = PCI_CFG_SPACE_SIZE; + + /* minimum 8 bytes per capability */ + ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; + + if (start) + pos = start; + + header = read_cfg(priv, pos, 4); + /* + * If we have no capabilities, this is indicated by cap ID, + * cap version and next pointer all being 0. + */ + if (header == 0) + return 0; + + while (ttl-- > 0) { + if (PCI_EXT_CAP_ID(header) == cap && pos != start) + return pos; + + pos = PCI_EXT_CAP_NEXT(header); + if (pos < PCI_CFG_SPACE_SIZE) + break; + + header = read_cfg(priv, pos, 4); + } + + return 0; +} + +u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, + int cap) +{ + return pci_generic_find_next_ext_capability(priv, read_cfg, 0, cap); +} +EXPORT_SYMBOL_GPL(pci_generic_find_ext_capability); + /** * pci_get_dsn - Read and return the 8-byte Device Serial Number * @dev: PCI device to query diff --git a/include/linux/pci.h b/include/linux/pci.h index 47b31ad724fa..48c2b45a4d04 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1205,6 +1205,11 @@ u8 pci_find_ht_capability(struct pci_dev *dev, int ht_cap); u8 pci_find_next_ht_capability(struct pci_dev *dev, u8 pos, int ht_cap); u16 pci_find_ext_capability(struct pci_dev *dev, int cap); u16 pci_find_next_ext_capability(struct pci_dev *dev, u16 pos, int cap); +typedef u32 (*pci_generic_read_cfg)(void *priv, int where, int size); +u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, + u8 cap); +u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, + u8 cap); struct pci_bus *pci_find_next_bus(const struct pci_bus *from); u16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap); u16 pci_find_dvsec_capability(struct pci_dev *dev, u16 vendor, u16 dvsec); @@ -2012,7 +2017,13 @@ static inline u8 pci_find_next_capability(struct pci_dev *dev, u8 post, int cap) { return 0; } static inline u16 pci_find_ext_capability(struct pci_dev *dev, int cap) { return 0; } - +typedef u32 (*pci_generic_read_cfg)(void *priv, int where, int size); +u8 pci_generic_find_capability(void *priv, pci_generic_read_cfg read_cfg, + u8 cap) +{ return 0; } +u16 pci_generic_find_ext_capability(void *priv, pci_generic_read_cfg read_cfg, + u8 cap) +{ return 0; } static inline u64 pci_get_dsn(struct pci_dev *dev) { return 0; }
Existing controller drivers (e.g., DWC, custom out-of-tree drivers) duplicate logic for scanning PCI capability lists. This creates maintenance burdens and risks inconsistencies. To resolve this: 1. Add pci_generic_find_capability() and pci_generic_find_ext_capability() in drivers/pci/pci.c, accepting controller-specific read functions and device data as parameters. 2. Refactor dwc_pcie_find_capability() and similar functions to utilize these new generic interfaces. 3. Update out-of-tree drivers to leverage the common implementation, eliminating code duplication. This approach: - Centralizes critical PCI capability scanning logic - Allows flexible adaptation to varied hardware access methods - Reduces future maintenance overhead - Aligns with kernel code reuse best practices Tested with DWC PCIe controller and CDNS PCIe drivers. Signed-off-by: Hans Zhang <18255117159@163.com> --- drivers/pci/pci.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 13 ++++++- 2 files changed, 95 insertions(+), 1 deletion(-)