简体   繁体   English

Linux PCI驱动程序调用init,但不进行探测

[英]Linux PCI Driver calls init, but not probe

I'm developing a driver for an FPGA-board connected to my machine via an PCIe expansion slot, and everything works great if the board is powered on prior to the PC. 我正在开发一个用于通过PCIe扩展插槽连接到我的机器的FPGA板的驱动程序,如果该板在PC之前打开电源,那么一切工作都很好。 However, if I book up my computer first and then the FPGA board, I get the rather unusual behavior of the device being recognized and loading my module (I see the "init" function called in my syslog), however the "probe" function is never called. 但是,如果先预订计算机然后再预订FPGA板,则会发现设备被识别并加载模块的异常现象(我在syslog中看到了“ init”函数),而“ probe”函数从未被调用。

I think this is due to an invalid BAR0. 我认为这是由于BAR0无效所致。 Output from dmesg when I power on the board: 当我打开开发板电源时, dmesg输出:

[   71.287587] pci 0000:3b:00.0: [0ae5:0001] type 00 class 0x000000
[   71.287613] pci 0000:3b:00.0: reg 0x10: [mem 0x00000000-0x0000ffff]
[   71.287821] pci 0000:3b:00.0: System wakeup disabled by ACPI
[   71.328537] my_driver:
[   71.328537] ****************************************************************
[   71.328542] my_driver: init debug=2

That first reg should be something like 0xb4000000-0xb400ffff but instead it's coming up as 0. (Like I said, it works perfectly if it's powered on before the computer). 该第一个reg应该类似于0xb4000000-0xb400ffff,但是它将变为0。(就像我说的那样,如果在计算机之前打开电源,它会完美工作)。

Is there an additional step required to get it to allocate this block? 是否需要其他步骤才能使其分配此块? Or somehow to indicate to the kernel that it needs to do this? 还是以某种方式向内核指示它需要这样做?

The solution wound up being a manual call to pci_assign_resource ( http://lxr.free-electrons.com/source/drivers/pci/setup-res.c#L283 ). 解决方案最终是通过手动调用pci_assign_resourcehttp://lxr.free-electrons.com/source/drivers/pci/setup-res.c#L283 )。

Calling this right before pci_enable_device caused the OS, rather than the BIOS, to allocate the required BAR's and now it all works! pci_enable_device之前调用此pci_enable_device导致操作系统(而不是BIOS)分配所需的BAR,现在一切正常!

I do still have to manually trigger a PCI bus rescan ( echo 1 > /sys/bus/pci/rescan ). 我仍然必须手动触发PCI总线重新扫描( echo 1 > /sys/bus/pci/rescan )。

Your PCI device must be powered up prior to the BIOS PCI enumeration phase. 您的PCI设备必须在BIOS PCI枚举阶段之前启动。 On enumeration phase, the BIOS tries to read the ID of the PCI devices that might be connected. 在枚举阶段,BIOS尝试读取可能已连接的PCI设备的ID。 If it reads invalid ID (0xfffff) it skips that PCI device. 如果读取的ID无效(0xfffff),它将跳过该PCI设备。

I don't have a reference, but AFAIK, you have about a second before you must populate the configuration space of the PCI. 我没有参考,但是AFAIK,您大约需要一秒钟才能填充PCI的配置空间。

Are you sure you register the PCI driver and don't return non-zero from mod_init? 您确定要注册PCI驱动程序并且不会从mod_init返回非零值吗? Please try to manually bind the device to your driver: 请尝试将设备手动绑定到驱动程序:

echo -n "0000:3b:00.0" > /sys/bus/pci/drivers/my_driver/bind

Unallocated BAR should not be an issue when loading the driver. 加载驱动程序时,未分配的BAR不应成为问题。

As for the BAR being 0 and HotPlug: find out what is your platform and if and how HotPlug is supported. 至于BAR为0和HotPlug:找出您的平台是什么以及是否以及如何支持HotPlug。 You need to have the right HotPlug driver in the kernel for this sort of thing to work. 您需要在内核中具有正确的HotPlug驱动程序,这样的事情才能起作用。 BARs are allocated by the kernel (or initially firmware/BIOS) so you can't set them to anything meaningful from the FPGA side - there you can only set the size. BAR由内核(或最初的固件/ BIOS)分配,因此您无法从FPGA端将它们设置为有意义的任何东西-在那只能设置大小。 Kernel has to do the rescanning and reassignment after device appears. 设备出现后,内核必须进行重新扫描和重新分配。 I vaguely recall that there should be some reservation going on during boot, otherwise kernel will not have to space to give to your devices' BAR and it will not reassign the windows on bridges below your device as they can be actively used by other devs. 我隐约记得在引导过程中应该保留一些空间,否则内核将不必空间来分配给设备的BAR,并且由于其他开发者可以积极使用它们,因此它也不会在设备下方的桥上重新分配窗口。 Other option is to just do the BAR programming yourself from the driver. 另一种选择是只从驱动程序自己进行BAR编程。 It ain't that hard but you would probably don't want to ship this kind of hacks to customers. 并不是那么困难,但是您可能不想将这种黑客手段发送给客户。 Also, even though your device does seem to come up fine, make sure you don't have HP disabled in FW/BIOS. 另外,即使您的设备看起来正常,也请确保在固件/ BIOS中没有禁用HP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM