0
我正在尝试编写一个内核模块来处理PCIe设备的MSI中断。我为我的驱动程序写了一个简单的骨架轮廓,当我尝试调用'pci_disable_msi(dev)'时,我得到无法处理内核NULL指针解除引用错误。我完全按照/Documentation/PCI/MSI-HOWTO.txt中的描述进行操作,在我看来,我不应该得到这个错误。这是一个错误还是我的设置不正确?根据发生的最后一次打印判断,当我调用pci_disable_msi()时,我确信它发生在fpga_remove()处。 (显然,这occures当我移动模块),pci_disable_msi糟糕问题
static struct pci_driver fpga_driver = {
.name = "PCIe_test",
.id_table = fpga_dev_table,
.probe = fpga_probe,
.remove = fpga_remove,
.suspend = fpga_suspend,
.resume = fpga_resume,
};
static irqreturn_t fpga_isr(int irq, struct pci_dev *dev)
{
printk(KERN_NOTICE "THIS is the ISR\n");
return IRQ_HANDLED;
}
static int setup_MSI_interrupt(struct pci_dev *dev, int num_msi)
{
int result;
result = pci_enable_msi(dev);
if(result)
{
printk(KERN_WARNING "Could not enable MSI\n");
return result;
}
printk(KERN_NOTICE "MSI has been enabled\n");
printk(KERN_NOTICE "dev->irq line is %d", dev->irq);
result = request_irq(dev->irq, fpga_isr, IRQF_SHARED, fpga_driver.name, dev);
printk(KERN_NOTICE "Using IRQ num %d\n", dev->irq);
if (result) {
dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev->irq, result);
goto exit1;
}
dev_info(&dev->dev, "FPGA using PCIe Interrupt\n");
return 0;
exit1:
return -1;
}
static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
printk(KERN_NOTICE "Probing driver\n");
switch(dev->vendor) {
case VENDOR://0x1708:
printk(KERN_NOTICE "Xilinx device found\n");
break;
default:
printk(KERN_NOTICE "Device found that does not match id: id = 0x%04X\n", dev->device);
};
int err = pci_enable_device(dev);
if (err) {
dev_err(&dev->dev, "Failed to enable FPGA PCI device (%d)\n", err);
goto exit;
}
err = setup_MSI_interrupt(dev, NUM_MSI);
if(err)
goto exit;
return 0;
exit:
return -1;
}
static void fpga_remove(struct pci_dev *dev)
{
printk(KERN_NOTICE "REMOVING IRQ # %d\n", dev->irq);
free_irq(dev->irq, dev);
printk(KERN_NOTICE "IRQ has been freed\n");
pci_disable_msi(dev); // This causes a NUll Pointer to be dereferenced but needs to be added
printk(KERN_NOTICE "MSI has been disabled\n");
}
static int __init fpga_init(void)
{
printk(KERN_NOTICE "Registering Driver\n");
return pci_register_driver(&fpga_driver);
return 0;
}
而且不要忘记调用'pci_disable_device()'在fpga_remove()。 – passerby