aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-06-10 21:44:26 -0500
committerMartin Roth <martinroth@google.com>2016-06-12 12:55:57 +0200
commit065b683618f8455dcb0bfc271a853d1c88a23734 (patch)
treec8faff6b29694b25d2b460011429f8d5727b0e2e /src/soc/intel/common
parent1ee6f0bdc826a13c7c52d82bd3d918b24de5eec0 (diff)
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)
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r--src/soc/intel/common/smihandler.c23
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);
}
}
}