this was in my queue since 2005/10/26
authorStefan Reinauer <stepan@openbios.org>
Tue, 11 Apr 2006 19:23:57 +0000 (19:23 +0000)
committerStefan Reinauer <stepan@openbios.org>
Tue, 11 Apr 2006 19:23:57 +0000 (19:23 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2252 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/devices/hypertransport.c

index c61efa6c7b893671b95fa9173af5521acd0a3e6d..6d37ab5764880325d57f0a40337dd8376eee5df8 100644 (file)
@@ -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);