diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/probe.c | 10 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 13 |
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index f4adba2d1dd3..12625d90f8b5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -163,9 +163,16 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int pos) { u32 l, sz, mask; + u16 orig_cmd; mask = type ? PCI_ROM_ADDRESS_MASK : ~0; + if (!dev->mmio_always_on) { + pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); + pci_write_config_word(dev, PCI_COMMAND, + orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); + } + res->name = pci_name(dev); pci_read_config_dword(dev, pos, &l); @@ -173,6 +180,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, pci_read_config_dword(dev, pos, &sz); pci_write_config_dword(dev, pos, l); + if (!dev->mmio_always_on) + pci_write_config_word(dev, PCI_COMMAND, orig_cmd); + /* * All bits set in sz means the device isn't working properly. * If the BAR isn't implemented, all bits must be 0. If it's a diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 3a81d9d44019..202efa6f57c4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -91,6 +91,19 @@ static void __devinit quirk_resource_alignment(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); +/* + * Decoding should be disabled for a PCI device during BAR sizing to avoid + * conflict. But doing so may cause problems on host bridge and perhaps other + * key system devices. For devices that need to have mmio decoding always-on, + * we need to set the dev->mmio_always_on bit. + */ +static void __devinit quirk_mmio_always_on(struct pci_dev *dev) +{ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) + dev->mmio_always_on = 1; +} +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on); + /* The Mellanox Tavor device gives false positive parity errors * Mark this device with a broken_parity_status, to allow * PCI scanning code to "skip" this now blacklisted device. |