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

问题描述 投票:0回答:5

我这里有Linux 4.4(我曾经在一个旧的内核上工作,它以同样的方式失败),带有一个PCIe连接的FPGA设备和一个驱动程序,它们都是我自己设计的。这些在正常条件下工作得很好,但现在我尝试让它们在热插拔条件下工作。这不是真正的硬件热插拔,我一直在尝试的是设备 sysfs 目录中常见的

echo 1 >remove
以及之后的
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 决定不在我设备的 BAR 上调用

request_resource()

linux-kernel fpga pci pci-e
5个回答
5
投票

看来我找到原因了。我在 PCIe 核心配置中将类代码保留为

0
(这是无效的),当设备在启动时存在时,它可以正常工作。输入一个合理的值(在我的例子中,
0x40000
表示多媒体视频设备,
0xff0000
表示“未注册设备”也有效)也使其可以在热插拔上工作。

Linux 似乎仅部分处理具有

0
类代码的设备。


2
投票

问题似乎是 FPGA 的 PCIe 核心的 PCIe 配置空间中的类定义不正确。确保 CLASS REGISTER 的高字节不是 0

我们在查看 dmesg 时遇到了类似的问题: “无法启用设备:BAR 0 ... ...未声明” 其次是 “pci_enable_device 失败”


0
投票

确实是类代码设置不正确。我建议设置

0x058000
,它对应于内存控制器。


0
投票

对于有类似问题的人来说,请参与进来。此错误也可能是由于设备树 (.dtsi) 不正确导致

我遇到了同样的问题。

can't enable device: BAR 0 [mem 0x839000000000-0x8390000fffff 64bit] not claimed

我的解决方案是将内存范围添加到linux设备树dtsi中。内存范围需要在设备树中可用。如果不是,您可能会收到同样的错误。您可以从

cat /proc/iomem
中阅读。


0
投票

你可以使用这个操作,它对我有用。

vi /ets/default/grub

并更改此行以禁用 i801_smbus 功能。

GRUB_CMDLINE_LINUX_DEFAULT="i2c-i801.disable_features=0x10 安静启动"

© www.soinside.com 2019 - 2024. All rights reserved.