Я пишу драйвер устройства linux для пользовательского устройства P CIe. Приложение пользовательского пространства отображается на этом устройстве и часто обращается к его памяти (чтение и запись). Устройство P CIe работает от внешнего источника питания, который может быть отключен во время работы.
При каждом сбросе устройства все операции чтения из памяти моего пользовательского приложения возвращают 0xFFFFFFFF
. Я хочу как можно быстрее обнаружить сброс устройства в драйвере ядра, поэтому я реализовал функцию обратного вызова error_detected
в соответствии с https://www.kernel.org/doc/html/latest/PCI/pci-error-recovery.html.
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
Я почти уверен, что устройство полностью выключено, поскольку во время сброса доступ к пространству конфигурации невозможен. Я ожидаю, что ядро вызовет функцию обратного вызова для обнаружения ошибок всякий раз, когда первый запрос чтения памяти к устройству завершится неудачно / истечет время ожидания. Правильно ли мое предположение?