linux-kernel - 删除/重新扫描后 pci_enable_device() 失败

标签 linux-kernel fpga pci pci-e

我这里有 Linux 4.4(我曾经在一个旧内核上工作,它以同样的方式失败)带有一个 PCIe 连接的 FPGA 设备和一个驱动程序,它们都是我自己设计的。这些在正常条件下运行良好,但现在我尝试使它们在热插拔条件下工作。这不是真正的硬件热插拔,我一直在尝试的是通常的 echo 1 >remove在设备的 sysfs 目录和 echo 1 >/sys/bus/pci/rescan 中然后。

设备重新出现后,我的驱动程序的初始化调用 pci_enable_device()记录时失败:

otscan 0000:02:00.0: can't enable device: BAR 0 [mem 0xf7e01000-0xf7e013ff] not claimed
otscan 0000:02:00.0: can't enable device: BAR 1 [mem 0xf7e00000-0xf7e00fff] not claimed
otscan 0000:02:00.0: can't enable device: BAR 2 [mem 0xf0200000-0xf020ffff 64bit pref] not claimed

(通常它会在第一个无人认领的资源之后停止,但我已经修改它以继续并确认实际上所有 BAR 都无人认领。)

这里的“未声明”是指 struct resource存在但没有父级,从我收集的信息来看,这是由 request_resource() 引起的从来没有被调用过。我不认为这是驱动程序问题,因为初始化例程在由于无法启用设备而中止之前不会做很多事情。

这留下了 FPGA(具有硬 IP PCIe 内核的 Altera Cyclone V)以及我可能在那里做错的事情,例如以某种方式错误处理总线重置。当通过 sysfs 重新插入时,该计算机中的其他 PCIe 设备可以工作。

我已经研究了一段时间,但仍然没有弄清楚为什么我的设备被 Linux 区别对待。我的设备有哪些可能的属性可以让 Linux 决定不调用 request_resource()在我设备的 BAR 上?

最佳答案

看起来我找到了原因。我已将类(class)代码保留为 0 (这是无效的)在 PCIe 核心配置中,当设备在启动时工作正常。输入一个合理的值(在我的案例中为多媒体视频设备 0x40000,对于“未注册设备”的 0xff0000 也有效)也使其适用于热插拔。

Linux 似乎只部分处理带有 0 的设备类(class)代码。

关于linux-kernel - 删除/重新扫描后 pci_enable_device() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46476844/

相关文章:

linux - 在串行端口上启用内核低级调试

linux - 有没有办法在linux内核中找到映射到进程虚拟内存区域的文件的文件名?

fpga - Quartus (Altera) 中 FPGA 设计的最大频率

c - 为何存在 Unresolved 包容性?

linux - 旧式 PCI 探测

linux - 为什么 PCIe TLP header 有 "Last DW BE"和 "First DW BE"?

c - unregister_chrdev 不会从/dev/中删除设备

linux-kernel - Linux内核 - 获取最后写入的内存块

vhdl - GHDL 模拟器不支持没有错误的 vhdl 属性?

linux - 为什么我不能在 Linux 上更改 PCI 配置寄存器?