Как правильно отключить устройство PCIe? - PullRequest
0 голосов
/ 08 октября 2019

Я пишу драйвер устройства в linux для конечной точки PCIe, реализованной в части Xilinx UltrascaleMPSoC FPGA. Я правильно реализовал функцию удаления. Я подключаю свое устройство с помощью адаптера к ПК, включаю устройство, включаю его конечную точку, а затем включаю ПК, и все работает правильно. Однако, когда я пытаюсь выгрузить модуль драйвера с помощью команды rmmod, процесс зависает.

Я просмотрел документацию по Linux и для pci_disable_device () Документация , там написано:

Обратите внимание, что мы фактически не отключаем устройство, пока все абоненты pci_enable_device () вызвали pci_disable_device ().

Означает ли это, что мой драйвер должен ждать до тех пор, пока все остальные драйверы pcie в linux не вызовут 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 () complete " и терминал зависает. Кроме того, я проверял файлы: / 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 не печатается. И процесс зависает :(

Пожалуйста, помогите

1 Ответ

0 голосов
/ 08 октября 2019

Трудно ответить без дополнительной информации о том, что вы действительно используете в своем драйвере.

Но я постараюсь дать вам ответ.

Означает ли это, что мой драйвер должен ждать до тех пор, пока все остальные драйверы pcie в linux не вызовут pci_disable_device () и только затем устройствоотключается?

Нет, это сделает непрактичным и не очень модульным.

Кажется, вы освобождаете страницы DMA. Как вы их распределяете? Используете ли вы последовательное распределение? Взгляните здесь , чтобы узнать, как правильно использовать DMA.

В остальном, можете ли вы попытаться переместить регионы освобождения до clear_master? Пример:

pci_disable_msi(pdev);
ioummap(ADDRESS);
pci_release_regions(pdev);
pci_clear_master(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);

Для получения дополнительной информации о том, как писать драйверы PCI, см. Документацию здесь . Он предоставляет много информации.

...