[PATCH] PCI: make MSI quirk inheritable from the pci bus
authorMichael S. Tsirkin <mst@mellanox.co.il>
Tue, 14 Feb 2006 16:52:22 +0000 (18:52 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 23 Mar 2006 22:35:14 +0000 (14:35 -0800)
It turns out AMD 8131 quirk only affects MSI for devices behind the 8131 bridge.
Handle this by adding a flags field in pci_bus, inherited from parent to child.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/msi.c
drivers/pci/probe.c
drivers/pci/quirks.c
include/linux/pci.h

index d5a67c1..4de1c17 100644 (file)
@@ -703,6 +703,9 @@ int pci_enable_msi(struct pci_dev* dev)
        if (dev->no_msi)
                return status;
 
+       if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+               return -EINVAL;
+
        temp = dev->irq;
 
        status = msi_init();
index 3bc0fcd..542e7df 100644 (file)
@@ -347,6 +347,7 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
        child->parent = parent;
        child->ops = parent->ops;
        child->sysdata = parent->sysdata;
+       child->bus_flags = parent->bus_flags;
        child->bridge = get_device(&bridge->dev);
 
        child->class_dev.class = &pcibus_class;
index d71c31d..4970f47 100644 (file)
@@ -575,8 +575,11 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
 { 
         unsigned char revid, tmp;
         
-       pci_msi_quirk = 1;
-       printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+       if (dev->subordinate) {
+               printk(KERN_WARNING "PCI: MSI quirk detected. "
+                      "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n");
+               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+       }
 
         if (nr_ioapics == 0) 
                 return;
index 2039da1..d4d533f 100644 (file)
@@ -95,6 +95,11 @@ enum pci_channel_state {
        pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,
 };
 
+typedef unsigned short __bitwise pci_bus_flags_t;
+enum pci_bus_flags {
+       PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1,
+};
+
 /*
  * The pci_dev structure is used to describe PCI devices.
  */
@@ -203,7 +208,7 @@ struct pci_bus {
        char            name[48];
 
        unsigned short  bridge_ctl;     /* manage NO_ISA/FBB/et al behaviors */
-       unsigned short  pad2;
+       pci_bus_flags_t bus_flags;      /* Inherited by child busses */
        struct device           *bridge;
        struct class_device     class_dev;
        struct bin_attribute    *legacy_io; /* legacy I/O for this bus */