+ struct ht_link prev;
+ u16 ctrl;
+
+ /* Initialize the hypertransport enumeration state. */
+ prev.dev = bus->dev;
+ prev.pos = bus->cap;
+ prev.ctrl_off = PCI_HT_CAP_HOST_CTRL;
+ prev.config_off = PCI_HT_CAP_HOST_WIDTH;
+ prev.freq_off = PCI_HT_CAP_HOST_FREQ;
+ prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
+
+ /* 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? */
+ if (ctrl & (1 << 6))
+ return;
+
+ /* Has the link failed? */
+ if (ctrl & (1 << 4)) {
+ /*
+ * 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(BIOS_ALERT, "Detected error on "
+ "Hypertransport link\n");
+ return;
+ }
+ }
+ } while ((ctrl & (1 << 5)) == 0);
+
+ /* Actually, only for one HT device HT chain, and unitid is 0. */
+#if CONFIG_HT_CHAIN_UNITID_BASE == 0
+ if (offset_unitid)
+ return;
+#endif
+
+ /* Check if is already collapsed. */
+ if ((!offset_unitid) || (offset_unitid
+ && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0)
+ && (CONFIG_HT_CHAIN_END_UNITID_BASE
+ < CONFIG_HT_CHAIN_UNITID_BASE))))) {