diff options
author | Michael S. Tsirkin <mst@mellanox.co.il> | 2006-02-14 11:52:22 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 17:35:14 -0500 |
commit | 6e325a62a0a228cd0222783802b53cce04551776 (patch) | |
tree | 5609f9e841024ca57ba8ee7a919955c7589444c7 | |
parent | e5548e960f38557825e50806b52cb24c9e730aa2 (diff) |
[PATCH] PCI: make MSI quirk inheritable from the pci bus
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>
-rw-r--r-- | drivers/pci/msi.c | 3 | ||||
-rw-r--r-- | drivers/pci/probe.c | 1 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 7 | ||||
-rw-r--r-- | include/linux/pci.h | 7 |
4 files changed, 15 insertions, 3 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d5a67c1bcb98..4de1c17ee573 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -703,6 +703,9 @@ int pci_enable_msi(struct pci_dev* dev) | |||
703 | if (dev->no_msi) | 703 | if (dev->no_msi) |
704 | return status; | 704 | return status; |
705 | 705 | ||
706 | if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) | ||
707 | return -EINVAL; | ||
708 | |||
706 | temp = dev->irq; | 709 | temp = dev->irq; |
707 | 710 | ||
708 | status = msi_init(); | 711 | status = msi_init(); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3bc0fcd71d03..542e7dfb371b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -347,6 +347,7 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
347 | child->parent = parent; | 347 | child->parent = parent; |
348 | child->ops = parent->ops; | 348 | child->ops = parent->ops; |
349 | child->sysdata = parent->sysdata; | 349 | child->sysdata = parent->sysdata; |
350 | child->bus_flags = parent->bus_flags; | ||
350 | child->bridge = get_device(&bridge->dev); | 351 | child->bridge = get_device(&bridge->dev); |
351 | 352 | ||
352 | child->class_dev.class = &pcibus_class; | 353 | child->class_dev.class = &pcibus_class; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d71c31df7fdf..4970f47be72c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -575,8 +575,11 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
575 | { | 575 | { |
576 | unsigned char revid, tmp; | 576 | unsigned char revid, tmp; |
577 | 577 | ||
578 | pci_msi_quirk = 1; | 578 | if (dev->subordinate) { |
579 | printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); | 579 | printk(KERN_WARNING "PCI: MSI quirk detected. " |
580 | "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n"); | ||
581 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | ||
582 | } | ||
580 | 583 | ||
581 | if (nr_ioapics == 0) | 584 | if (nr_ioapics == 0) |
582 | return; | 585 | return; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 2039da1f3672..d4d533fa5d30 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -95,6 +95,11 @@ enum pci_channel_state { | |||
95 | pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, | 95 | pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | typedef unsigned short __bitwise pci_bus_flags_t; | ||
99 | enum pci_bus_flags { | ||
100 | PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1, | ||
101 | }; | ||
102 | |||
98 | /* | 103 | /* |
99 | * The pci_dev structure is used to describe PCI devices. | 104 | * The pci_dev structure is used to describe PCI devices. |
100 | */ | 105 | */ |
@@ -203,7 +208,7 @@ struct pci_bus { | |||
203 | char name[48]; | 208 | char name[48]; |
204 | 209 | ||
205 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ | 210 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ |
206 | unsigned short pad2; | 211 | pci_bus_flags_t bus_flags; /* Inherited by child busses */ |
207 | struct device *bridge; | 212 | struct device *bridge; |
208 | struct class_device class_dev; | 213 | struct class_device class_dev; |
209 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ | 214 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ |