我正在为自定义PCIe设备编写Linux内核设备驱动程序。 用户空间应用程序映射到该设备,并频繁访问其内存(读和写)。 PCIe设备由外部电源驱动,该外部电源在运行时可能会关闭。
无论何时重置设备,我的用户应用程序的所有内存读取都会返回0xFFFFFFFF
。
我想尽快在内核驱动程序中检测设备重置,因此我根据https://www.kernel.org/doc/html/latest/PCI/pci-error-recovery.html实现了error_detected
回调函数。
static pci_ers_result_t mydevice_error_detected(struct pci_dev* dev, pci_channel_state_t state) {
printk(KERN_ALERT "mydevice PCI error detected");
return PCI_ERS_RESULT_DISCONNECT;
}
static struct pci_error_handlers mydevice_error_handlers = {
.error_detected = mydevice_error_detected,
.slot_reset = mydevice_slot_reset,
.resume = mydevice_resume
};
static struct pci_driver mydevice_driver = {
.name = "mydevice",
.id_table = mydevice_ids,
.probe = mydevice_probe,
.remove = mydevice_remove,
.suspend = mydevice_suspend,
.resume = mydevice_resume,
.err_handler = &mydevice_error_handlers
};
但是,即使用户空间应用程序不断尝试读取设备内存失败(并获得mydevice_error_detected
),设备重置期间也不会调用0xFFFFFFFF
。
此外,lspci
仍在PCI重新扫描后列出该设备,即使该设备已关闭:
01:00.0 Unassigned class [ff00]: MyVendorId Device 5a00 (rev ff)
唯一的区别是,当设备处于关闭状态时,“ rev ff
”出现在行的末尾。否则lspci
返回
01:00.0 Unassigned class [ff00]: MyVendorId Device 5a00
我非常确定该设备已完全关闭,因为在重置期间无法访问配置空间。 我希望每当对设备的第一个内存读取请求失败/超时时,内核都会调用错误检测回调。我的假设正确吗?