Обработчик ошибок PCI в драйвере ядра никогда не вызывается, даже если устройство выключено - PullRequest
0 голосов
/ 24 марта 2020

Я пишу драйвер устройства 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

Я почти уверен, что устройство полностью выключено, поскольку во время сброса доступ к пространству конфигурации невозможен. Я ожидаю, что ядро ​​вызовет функцию обратного вызова для обнаружения ошибок всякий раз, когда первый запрос чтения памяти к устройству завершится неудачно / истечет время ожидания. Правильно ли мое предположение?

...