如何识别pci_reset_bus()函数签名?求跨内核编译兼容方案
适配不同内核版本的
pci_reset_bus()函数签名问题解决方案 1. 正确识别pci_reset_bus()的函数签名
不要依赖LINUX_VERSION_CODE做版本判断——部分发行版会将新内核的特性backport到老版本内核中,导致版本号与实际函数签名不匹配。最可靠的方式是编译时直接检查函数的参数类型,利用编译器内建函数实现:
// 必须在包含 <linux/pci.h> 之后进行判断 #include <linux/pci.h> #if __builtin_types_compatible_p(typeof(pci_reset_bus), int (*)(struct pci_dev *)) #define PCI_RESET_BUS_TAKES_DEV 1 #else #define PCI_RESET_BUS_TAKES_DEV 0 #endif
这个判断会直接对比pci_reset_bus的函数指针类型与目标签名是否兼容,完全不受内核版本号或发行版补丁的影响。
2. 跨内核兼容的稳健解决方案
基于上面的编译时判断,封装一层兼容函数,上层代码统一调用这个封装函数即可:
/** * my_pci_reset_bus - 兼容不同版本的PCI总线重置函数 * @dev: 目标PCI设备 * * 自动适配新旧版本的pci_reset_bus签名,无需关心底层实现差异 */ static inline int my_pci_reset_bus(struct pci_dev *dev) { if (!dev) return -EINVAL; #if PCI_RESET_BUS_TAKES_DEV return pci_reset_bus(dev); #else // 旧版本需要传入设备所属的bus结构体 return pci_reset_bus(dev->bus); #endif }
额外注意事项
- 确保在包含
<linux/pci.h>之后再定义上述判断宏和兼容函数,否则编译器无法获取pci_reset_bus的正确声明。 - 若需要支持非GCC编译器(如Clang),
__builtin_types_compatible_p同样适用,无需额外修改。
内容的提问来源于stack exchange,提问作者Itay Avraham
相关产品推荐
相关产品推荐

