diff options
author | Stefan Reinauer <stepan@openbios.org> | 2006-04-11 19:23:57 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2006-04-11 19:23:57 +0000 |
commit | cf648c9a99c59f25400f198b99de2f92e57db349 (patch) | |
tree | ed7c96e1e7e0ba66185154f597d958ddf45f9760 /src | |
parent | fbce0ffb92d8665c9cef5cb7be4d9fa6646bd7f2 (diff) |
this was in my queue since 2005/10/26
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2252 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/hypertransport.c | 40 |
1 files 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); |