From: Keir Fraser Date: Tue, 24 Nov 2009 14:45:19 +0000 (+0000) Subject: xen: Dont call msi_unmap_pirq() if did not enable msi X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5285405772c205113d0dd6010761cbe931c85866;p=people%2Froyger%2Flinux-2.6.18-xen.git xen: Dont call msi_unmap_pirq() if did not enable msi When device driver unload, it may call pci_disable_msi(), if msi did not enabled but do msi_unmap_pirq(), then later driver reload and without msi, then will failed in request_irq() for irq_desc[irq]->chip valie is no_irq_chip. So when did not enable msi during driver initializing, then unloaded driver will not try to disable it. How to reproduce it: At the server with QLogic 25xx, try to reload qla2xxx will hit it. Signed-off-by: Joe Jin --- diff --git a/drivers/pci/msi-xen.c b/drivers/pci/msi-xen.c index f4e3d725..30fcaa94 100644 --- a/drivers/pci/msi-xen.c +++ b/drivers/pci/msi-xen.c @@ -618,6 +618,7 @@ int pci_enable_msi(struct pci_dev* dev) return ret; dev->irq = evtchn_map_pirq(-1, dev->irq); + dev->msi_enabled = 1; msi_dev_entry->default_irq = temp; return ret; @@ -662,9 +663,15 @@ void pci_disable_msi(struct pci_dev* dev) #ifdef CONFIG_XEN_PCIDEV_FRONTEND if (!is_initial_xendomain()) { + if (!(dev->msi_enabled)) { + printk(KERN_INFO "PCI: %s: Device did not enabled MSI.\n", + pci_name(dev)); + return; + } evtchn_map_pirq(dev->irq, 0); pci_frontend_disable_msi(dev); dev->irq = msi_dev_entry->default_irq; + dev->msi_enabled = 0; return; } #endif @@ -673,6 +680,12 @@ void pci_disable_msi(struct pci_dev* dev) if (!pos) return; + if (!(dev->msi_enabled)) { + printk(KERN_INFO "PCI: %s: Device did not enabled MSI.\n", + pci_name(dev)); + return; + } + pirq = dev->irq; /* Restore dev->irq to its default pin-assertion vector */ dev->irq = msi_dev_entry->default_irq;