I am writing a device driver in linux for PCIe endpoint implemented on Xilinx UltrascaleMPSoC FPGA part. I have implemented the remove function correctly. I connect my device using an adapter to my PC, turn on device, enable its Endpoint and then turn on PC and everything works correctly. However, when I try to unload the driver module using rmmod command, the process hangs.
I went through Linux documentation and for pci_disable_device() documentation, it says
Note we don't actually disable the device until all callers of pci_enable_device() have called pci_disable_device().
Does it mean, my driver has to wait untill every other pcie driver in linux calls pci_disable_device() and only then device gets disabled? I really doubt upon this :(
I tried using modprobe -r and also listed the module usage count using "lsmod". lsmod shows usage count as "0". But still I am not able to unload the module :( I also added print statements.
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");
}
Expected: The device must get disabled. I can't conclude. When I do a dmesg in another terminal, I get prints till "disable_device() complete" and the terminal hangs.Also,I checked the files: /proc/iomem and /proc/interrupts-> when I unload the module, corresponding entries of my device is removed in both of my files! I only complete the execution of pci_disable_device() and the process hangs.
Note: Only the rmmod process hangs and I cannot use the current terminal, but I can open another terminal, do all things.
Finally, when the do a restart, the system hangs again and everytime, I am doing force restart by holding power button for 10-15 seconds. Check this reboot_hang
Why is the pci_release_regions() hanging my system even though lsmod shows my module usage count as "0".
Thanks in advance :)
Also, should I interchange pci_disable_device() and pci_release_regions() methods in above code? -> I tried this as well, but then I get prints till release_regions() complete but disable_device complete is not printed. And process hangs :(
Please help