From cf648c9a99c59f25400f198b99de2f92e57db349 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Tue, 11 Apr 2006 19:23:57 +0000 Subject: [PATCH] this was in my queue since 2005/10/26 git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2252 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/devices/hypertransport.c | 40 +++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index c61efa6c7b..6d37ab5764 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -278,7 +278,20 @@ static void ht_collapse_early_enumeration(struct bus *bus, unsigned offset_uniti } /* Has the link failed? */ if (ctrl & (1 << 4)) { - return; + /* + * Either the link has failed, or we have + * a CRC error. + * Sometimes this can happen due to link + * retrain, so lets knock it down and see + * if its transient + */ + ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc + pci_write_config16(prev.dev, prev.pos + prev.ctrl_off, ctrl); + ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + if (ctrl & ((1 << 4) | (1 << 8))) { + printk_alert("Detected error on Hypertransport Link\n"); + return; + } } } while((ctrl & (1 << 5)) == 0); @@ -382,12 +395,25 @@ unsigned int hypertransport_scan_chain(struct bus *bus, /* Wait until the link initialization is complete */ do { ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); - /* Is this the end of the hypertransport chain? - * Has the link failed? - * If so further scanning is pointless. - */ - if (ctrl & ((1 << 6) | (1 << 4))) { - goto end_of_chain; + + if (ctrl & (1 << 6)) + goto end_of_chain; // End of chain + + if (ctrl & ((1 << 4) | (1 << 8))) { + /* + * Either the link has failed, or we have + * a CRC error. + * Sometimes this can happen due to link + * retrain, so lets knock it down and see + * if its transient + */ + ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc + pci_write_config16(prev.dev, prev.pos + prev.ctrl_off, ctrl); + ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + if (ctrl & ((1 << 4) | (1 << 8))) { + printk_alert("Detected error on Hypertransport Link\n"); + goto end_of_chain; + } } } while((ctrl & (1 << 5)) == 0);