linux device driver - pci_disable_msi Oops Bug -
linux device driver - pci_disable_msi Oops Bug -
i trying write kernel module handle msi interrupts pcie device. have written simple skeleton outline driver , whenever seek phone call 'pci_disable_msi(dev)' unable handle kernel null pointer dereference error. next along described /documentation/pci/msi-howto.txt , seems me should not getting error. bug or setup incorrect? judging lastly print occures, pretty sure happening @ fpga_remove() when phone call pci_disable_msi(). (clearly occures when removing module)
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 isr\n"); homecoming 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"); homecoming result; } printk(kern_notice "msi has been enabled\n"); printk(kern_notice "dev->irq line %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 allocate irq %d: %d\n", dev->irq, result); goto exit1; } dev_info(&dev->dev, "fpga using pcie interrupt\n"); homecoming 0; exit1: homecoming -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 not match id: id = 0x%04x\n", dev->device); }; int err = pci_enable_device(dev); if (err) { dev_err(&dev->dev, "failed enable fpga pci device (%d)\n", err); goto exit; } err = setup_msi_interrupt(dev, num_msi); if(err) goto exit; homecoming 0; exit: homecoming -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); // causes null pointer dereferenced needs added printk(kern_notice "msi has been disabled\n"); } static int __init fpga_init(void) { printk(kern_notice "registering driver\n"); homecoming pci_register_driver(&fpga_driver); homecoming 0; }
you should not utilize struct pci_dev
void *dev_id
parameter in request_irq(...)
, free_irq(...)
functions. of import phone call them right , same unique dev_id
parameter interrupt. doing not cause kernel panic @ pci_disable_msi()
on removing module.
read more here: what dev_id parameter in request_irq?
linux-device-driver kernel-module pci-e
Comments
Post a Comment