[PATCH] MSI-X: fix resume crash
authorEric W. Biederman <ebiederm@xmission.com>
Wed, 28 Mar 2007 13:36:09 +0000 (15:36 +0200)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 28 Mar 2007 20:59:37 +0000 (13:59 -0700)
So I think the right solution is to simply make pci_enable_device just
flip enable bits and move the rest of the work someplace else.

However a thorough cleanup is a little extreme for this point in the
release cycle, so I think a quick hack that makes the code not stomp the
irq when msi irq's are enabled should be the first fix.  Then we can
later make the code not change the irqs at all.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/cris/arch-v32/drivers/pci/bios.c
arch/frv/mb93090-mb00/pci-vdk.c
arch/i386/pci/common.c
arch/ia64/pci/pci.c

index a2b9c60c2777e6cf39b94b0789fccf15307ced19..5b79a7a772d4cae43c230429820acfff4a5d15e8 100644 (file)
@@ -100,7 +100,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        if ((err = pcibios_enable_resources(dev, mask)) < 0)
                return err;
 
-       return pcibios_enable_irq(dev);
+       if (!dev->msi_enabled)
+               pcibios_enable_irq(dev);
+       return 0;
 }
 
 int pcibios_assign_resources(void)
index f7279d78995a8580157f2a77f25a124009f50ce6..0b581e3cf7c75602cfc122d9f58098620dccecdc 100644 (file)
@@ -466,6 +466,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
        if ((err = pcibios_enable_resources(dev, mask)) < 0)
                return err;
-       pcibios_enable_irq(dev);
+       if (!dev->msi_enabled)
+               pcibios_enable_irq(dev);
        return 0;
 }
index 9484366653856afe6bf1ffacbe32072a08f14171..3f78d4d8ecf31a00798e00790e52a81404a4cee0 100644 (file)
@@ -434,11 +434,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        if ((err = pcibios_enable_resources(dev, mask)) < 0)
                return err;
 
-       return pcibios_enable_irq(dev);
+       if (!dev->msi_enabled)
+               return pcibios_enable_irq(dev);
+       return 0;
 }
 
 void pcibios_disable_device (struct pci_dev *dev)
 {
-       if (pcibios_disable_irq)
+       if (!dev->msi_enabled && pcibios_disable_irq)
                pcibios_disable_irq(dev);
 }
index 474d179966dc02e221ee81d8083ae566e255e804..f8bcccd6d41774630e8a31ce84baf8eadab22b1d 100644 (file)
@@ -557,14 +557,18 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
        if (ret < 0)
                return ret;
 
-       return acpi_pci_irq_enable(dev);
+       if (!dev->msi_enabled)
+               return acpi_pci_irq_enable(dev);
+       return 0;
 }
 
 void
 pcibios_disable_device (struct pci_dev *dev)
 {
        BUG_ON(atomic_read(&dev->enable_cnt));
-       acpi_pci_irq_disable(dev);
+       if (!dev->msi_enabled)
+               acpi_pci_irq_disable(dev);
+       return 0;
 }
 
 void