diff options
author | Aaron Durbin <adurbin@chromium.org> | 2016-06-10 21:44:26 -0500 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-06-12 12:55:57 +0200 |
commit | 065b683618f8455dcb0bfc271a853d1c88a23734 (patch) | |
tree | c8faff6b29694b25d2b460011429f8d5727b0e2e | |
parent | 1ee6f0bdc826a13c7c52d82bd3d918b24de5eec0 (diff) | |
download | coreboot-065b683618f8455dcb0bfc271a853d1c88a23734.tar.xz |
soc/intel/common: don't infinitely recurse in busmaster_disable_on_bus()
If a bridge has the primary bus equal to the secondary bus the
busmaster_disable_on_bus() will infinitely call itself. Avoid the
inifinite recursion by checking current bus number against the
secondary bus number.
BUG=chrome-os-partner:54262
TEST=Ran on reef. Able to actually get the chipset to assert SLP_Sx
signals which means no more infinite recursion.
Change-Id: I52b21fbba24e6a652ea8f9f87f5f49f60109c8f2
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/15157
Reviewed-by: Furquan Shaikh <furquan@google.com>
Tested-by: build bot (Jenkins)
-rw-r--r-- | src/soc/intel/common/smihandler.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/soc/intel/common/smihandler.c b/src/soc/intel/common/smihandler.c index 0b220e201c..5915587b50 100644 --- a/src/soc/intel/common/smihandler.c +++ b/src/soc/intel/common/smihandler.c @@ -104,15 +104,24 @@ static void busmaster_disable_on_bus(int bus) reg32 &= ~PCI_COMMAND_MASTER; pci_write_config32(dev, PCI_COMMAND, reg32); - /* If this is a bridge, then follow it. */ + /* If it's not a bridge, move on. */ hdr = pci_read_config8(dev, PCI_HEADER_TYPE); hdr &= 0x7f; - if (hdr == PCI_HEADER_TYPE_BRIDGE || - hdr == PCI_HEADER_TYPE_CARDBUS) { - unsigned int buses; - buses = pci_read_config32(dev, PCI_PRIMARY_BUS); - busmaster_disable_on_bus((buses >> 8) & 0xff); - } + if (hdr != PCI_HEADER_TYPE_BRIDGE && + hdr != PCI_HEADER_TYPE_CARDBUS) + continue; + + /* + * If secondary bus is equal to current bus bypass + * the bridge because it's likely unconfigured and + * would cause infinite recursion. + */ + int secbus = pci_read_config8(dev, PCI_SECONDARY_BUS); + + if (secbus == bus) + continue; + + busmaster_disable_on_bus(secbus); } } } |