summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-05-23 03:05:27 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 12:00:00 -0700
commit1edab4a164b229807853682f7ff7858c11dd3481 (patch)
treeb2b65bb914850270f5e22f9b4c49ef371c0f20b6
parent74d0a988d3aa359b6b8a8536c8cb92cce02ca5d5 (diff)
[PATCH] PCI: AMD 8131 MSI quirk called too late, bus_flags not inherited ?
The PCI_BUS_FLAGS_NO_MSI bus flags does not appear do be inherited correctly from the amd8131 MSI quirk to its parent busses. It makes devices behind a bridge behind amd8131 try to enable MSI while the amd8131 does not support it. We fix this by looking at flags of all parent busses in pci_enable_msi() and pci_enable_msix(). By the way, also add the missing dev->no_msi check in pci_enable_msix() Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/msi.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f8105783da2..4aea563bda6 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -916,6 +916,7 @@ static int msix_capability_init(struct pci_dev *dev,
**/
int pci_enable_msi(struct pci_dev* dev)
{
+ struct pci_bus *bus;
int pos, temp, status = -EINVAL;
u16 control;
@@ -925,8 +926,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;
+ for (bus = dev->bus; bus; bus = bus->parent)
+ if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+ return -EINVAL;
temp = dev->irq;
@@ -1162,6 +1164,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
**/
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
{
+ struct pci_bus *bus;
int status, pos, nr_entries, free_vectors;
int i, j, temp;
u16 control;
@@ -1170,6 +1173,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
if (!pci_msi_enable || !dev || !entries)
return -EINVAL;
+ if (dev->no_msi)
+ return -EINVAL;
+
+ for (bus = dev->bus; bus; bus = bus->parent)
+ if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+ return -EINVAL;
+
status = msi_init();
if (status < 0)
return status;