我正在 linux 中为 Xilinx UltrascaleMPSoC FPGA 部件上实现的 PCIe 端点编写设备驱动程序。我已经正确实现了删除功能。我使用适配器将我的设备连接到我的电脑,打开设备,启用其端点,然后打开电脑,一切正常。但是,当我尝试使用 rmmod 命令卸载驱动程序模块时,进程挂起。
我浏览了 Linux 文档和 pci_disable_device()文档,它说
请注意,直到 pci_enable_device() 的所有调用者都调用了 pci_disable_device(),我们才真正禁用设备。
这是否意味着,我的驱动程序必须等到 linux 中的所有其他 pcie 驱动程序调用 pci_disable_device() ,然后设备才会被禁用?我真的很怀疑这一点:(
我尝试使用 modprobe -r 并使用“lsmod”列出了模块使用计数。lsmod 将使用计数显示为“0”。但是我仍然无法卸载模块:(我还添加了打印语句。
void remove(struct pci_dev pdev)
{
pci_unmap_single(pdev, privdata->dma_mem,
PAGE_SIZE * (1 << memorder),
PCI_DMA_FROMDEVICE);
printk(KERN_INFO"unmap_single() complete\n");
free_pages ((unsigned long) privdata->mem, memorder);
printk(KERN_INFO"free_pages() complete\n");
free_irq(pdev->irq, privdata);
printk(KERN_INFO"free_irq() complete\n");
pci_disable_msi(pdev);
printk(KERN_INFO"MSI disable complete\n");
pci_clear_master(pdev); /* Nobody seems to do this */
printk(KERN_INFO"clear_master() complete\n");
pci_iounmap(pdev, privdata->registers);
printk(KERN_INFO"iounmap() complete\n");
pci_disable_device(pdev);
printk(KERN_INFO"disable_device() complete\n");
pci_release_regions(pdev);
printk(KERN_INFO"release_regions() complete\n");
}
预期:设备必须被禁用。我无法得出结论。当我在另一个终端中执行 dmesg 时,我得到打印,直到“ disable_device() 完成”并且终端挂起。此外,我检查了文件:/proc/iomem 和 /proc/interrupts-> 当我卸载模块时,相应的条目我的两个文件中都删除了我的设备!我只完成了 pci_disable_device() 的执行,进程挂起。
注意:只有 rmmod 进程挂起,我不能使用当前终端,但我可以打开另一个终端,做所有事情。
最后,当重新启动时,系统再次挂起,每次我都通过按住电源按钮 10-15 秒来强制重启。检查这个reboot_hang
为什么 pci_release_regions() 挂起我的系统,即使 lsmod 显示我的模块使用计数为“0”。
在此先感谢:)另外,我应该在上面的代码中交换pci_disable_device()
和方法吗?pci_release_regions()
-> 我也试过了,但是直到 release_regions() 完成后我才打印出来,但 disable_device complete 没有打印出来。并且进程挂起:(
请帮忙