]> xenbits.xensource.com Git - people/royger/linux-2.6.18-xen.git/commitdiff
xen: Dont call msi_unmap_pirq() if did not enable msi
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 24 Nov 2009 14:45:19 +0000 (14:45 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 24 Nov 2009 14:45:19 +0000 (14:45 +0000)
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 <joe.jin@oracle.com>
drivers/pci/msi-xen.c

index f4e3d725ef0f255d2376ea10a1d46db3b31ced54..30fcaa94e2b0765a28e4d82a999aaf32caabcfc3 100644 (file)
@@ -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;