Skip to content

Commit

Permalink
Merge branch 'pci/bjorn-disable-decode' into next
Browse files Browse the repository at this point in the history
* pci/bjorn-disable-decode:
  PCI: disable MEM decoding while updating 64-bit MEM BARs
  PCI: leave MEM and IO decoding disabled during 64-bit BAR sizing, too
  • Loading branch information
Bjorn Helgaas committed Jul 10, 2012
2 parents 9349b44 + 9aac537 commit d68e70c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
6 changes: 3 additions & 3 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,6 @@ 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
Expand Down Expand Up @@ -276,6 +273,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
}

out:
if (!dev->mmio_always_on)
pci_write_config_word(dev, PCI_COMMAND, orig_cmd);

return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
fail:
res->flags = 0;
Expand Down
18 changes: 18 additions & 0 deletions drivers/pci/setup-res.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
void pci_update_resource(struct pci_dev *dev, int resno)
{
struct pci_bus_region region;
bool disable;
u16 cmd;
u32 new, check, mask;
int reg;
enum pci_bar_type type;
Expand Down Expand Up @@ -67,6 +69,18 @@ void pci_update_resource(struct pci_dev *dev, int resno)
new |= PCI_ROM_ADDRESS_ENABLE;
}

/*
* We can't update a 64-bit BAR atomically, so when possible,
* disable decoding so that a half-updated BAR won't conflict
* with another device.
*/
disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
if (disable) {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
pci_write_config_word(dev, PCI_COMMAND,
cmd & ~PCI_COMMAND_MEMORY);
}

pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);

Expand All @@ -84,6 +98,10 @@ void pci_update_resource(struct pci_dev *dev, int resno)
"(high %#08x != %#08x)\n", resno, new, check);
}
}

if (disable)
pci_write_config_word(dev, PCI_COMMAND, cmd);

res->flags &= ~IORESOURCE_UNSET;
dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
resno, res, (unsigned long long)region.start,
Expand Down

0 comments on commit d68e70c

Please sign in to comment.