Index: svn/src/include/device/device.h
===================================================================
--- svn.orig/src/include/device/device.h
+++ svn/src/include/device/device.h
@@ -40,8 +40,9 @@ struct device_operations {
 struct bus {
 	device_t 	dev;		/* This bridge device */
 	device_t 	children;	/* devices behind this bridge */
+	struct bus	*next;		/* The next bridge on this device */
 	unsigned	bridge_ctrl;	/* Bridge control register */
-	unsigned char	link;		/* The index of this link */
+	unsigned char	link_num;	/* The index of this link */
 	uint16_t	secondary; 	/* secondary bus number */
 	uint16_t	subordinate;	/* max subordinate bus number */
 	unsigned char   cap;		/* PCi capability offset */
@@ -49,8 +50,6 @@ struct bus {
 	unsigned	disable_relaxed_ordering : 1;
 };
 
-#define MAX_RESOURCES 24
-#define MAX_LINKS    8
 /*
  * There is one device structure for each slot-number/function-number
  * combination:
@@ -79,9 +78,7 @@ struct device {
 	/* links are (downstream) buses attached to the device, usually a leaf
 	 * device with no children has 0 buses attached and a bridge has 1 bus
 	 */
-	struct bus link[MAX_LINKS];
-	/* number of buses attached to the device */
-	unsigned int links;
+	struct bus *link_list;
 
 	struct device_operations *ops;
 	const struct chip_operations *chip_ops;
@@ -96,6 +93,7 @@ extern struct device	dev_root;
 extern struct device	*all_devices;	/* list of all devices */
 
 extern struct resource	*free_resources;
+extern struct bus	*free_links;
 
 /* Generic device interface functions */
 device_t alloc_dev(struct bus *parent, struct device_path *path);
Index: svn/src/devices/device.c
===================================================================
--- svn.orig/src/devices/device.c
+++ svn/src/devices/device.c
@@ -66,7 +66,6 @@ DECLARE_SPIN_LOCK(dev_lock)
 device_t alloc_dev(struct bus *parent, struct device_path *path)
 {
 	device_t dev, child;
-	int link;
 
 	spin_lock(&dev_lock);
 
@@ -82,12 +81,6 @@ device_t alloc_dev(struct bus *parent, s
 	memset(dev, 0, sizeof(*dev));
 	memcpy(&dev->path, path, sizeof(*path));
 
-	/* Initialize the back pointers in the link fields. */
-	for (link = 0; link < MAX_LINKS; link++) {
-		dev->link[link].dev = dev;
-		dev->link[link].link = link;
-	}
-
 	/* By default devices are enabled. */
 	dev->enabled = 1;
 
@@ -132,11 +125,11 @@ static void read_resources(struct bus *b
 	struct device *curdev;
 
 	printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev), __func__,
-		    bus->secondary, bus->link);
+		    bus->secondary, bus->link_num);
 
 	/* Walk through all devices and find which resources they need. */
 	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
-		int i;
+		struct bus *link;
 		if (!curdev->enabled) {
 			continue;
 		}
@@ -148,11 +141,11 @@ static void read_resources(struct bus *b
 		curdev->ops->read_resources(curdev);
 
 		/* Read in the resources behind the current device's links. */
-		for (i = 0; i < curdev->links; i++)
-			read_resources(&curdev->link[i]);
+		for (link = curdev->link_list; link; link = link->next)
+			read_resources(link);
 	}
 	printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
-		    dev_path(bus->dev), bus->secondary, bus->link);
+		    dev_path(bus->dev), bus->secondary, bus->link_num);
 }
 
 struct pick_largest_state {
@@ -257,13 +250,13 @@ static void compute_resources(struct bus
 	for (dev = bus->children; dev; dev = dev->sibling) {
 		struct resource *child_bridge;
 
-		if (!dev->links)
+		if (!dev->link_list)
 			continue;
 
 		/* Find the resources with matching type flags. */
 		for (child_bridge = dev->resource_list; child_bridge;
 		     child_bridge = child_bridge->next) {
-			unsigned link;
+			struct bus* link;
 
 			if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
 			    (child_bridge->flags & type_mask) != type)
@@ -275,8 +268,15 @@ static void compute_resources(struct bus
 			 * need it separated.  Add the PREFETCH flag to the
 			 * type_mask and type.
 			 */
-			link = IOINDEX_LINK(child_bridge->index);
-			compute_resources(&dev->link[link], child_bridge,
+			link = dev->link_list;
+			while (link && link->link_num !=
+					IOINDEX_LINK(child_bridge->index))
+				link = link->next;
+			if (link == NULL)
+				printk(BIOS_ERR, "link %ld not found on %s\n",
+				       IOINDEX_LINK(child_bridge->index),
+				       dev_path(dev));
+			compute_resources(link, child_bridge,
 					  type_mask | IORESOURCE_PREFETCH,
 					  type | (child_bridge->flags &
 						  IORESOURCE_PREFETCH));
@@ -505,13 +505,13 @@ static void allocate_resources(struct bu
 	for (dev = bus->children; dev; dev = dev->sibling) {
 		struct resource *child_bridge;
 
-		if (!dev->links)
+		if (!dev->link_list)
 			continue;
 
 		/* Find the resources with matching type flags. */
 		for (child_bridge = dev->resource_list; child_bridge;
 		     child_bridge = child_bridge->next) {
-			unsigned link;
+			struct bus* link;
 
 			if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
 			    (child_bridge->flags & type_mask) != type)
@@ -523,8 +523,15 @@ static void allocate_resources(struct bu
 			 * need it separated.  Add the PREFETCH flag to the
 			 * type_mask and type.
 			 */
-			link = IOINDEX_LINK(child_bridge->index);
-			allocate_resources(&dev->link[link], child_bridge,
+			link = dev->link_list;
+			while (link && link->link_num !=
+			               IOINDEX_LINK(child_bridge->index))
+				link = link->next;
+			if (link == NULL)
+				printk(BIOS_ERR, "link %ld not found on %s\n",
+				       IOINDEX_LINK(child_bridge->index),
+				       dev_path(dev));
+			allocate_resources(link, child_bridge,
 					   type_mask | IORESOURCE_PREFETCH,
 					   type | (child_bridge->flags &
 						   IORESOURCE_PREFETCH));
@@ -551,7 +558,7 @@ static void constrain_resources(struct d
 	struct device *child;
 	struct resource *res;
 	struct resource *lim;
-	int i;
+	struct bus *link;
 
 	printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
 
@@ -592,8 +599,8 @@ static void constrain_resources(struct d
 	}
 
 	/* Descend into every enabled child and look for fixed resources. */
-	for (i = 0; i < dev->links; i++)
-		for (child = dev->link[i].children; child;
+	for (link = dev->link_list; link; link = link->next)
+		for (child = link->children; child;
 		     child = child->sibling)
 			if (child->enabled)
 				constrain_resources(child, limits);
@@ -757,7 +764,7 @@ void assign_resources(struct bus *bus)
 	struct device *curdev;
 
 	printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
-		    dev_path(bus->dev), bus->secondary, bus->link);
+		    dev_path(bus->dev), bus->secondary, bus->link_num);
 
 	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
 		if (!curdev->enabled || !curdev->resource_list) {
@@ -771,7 +778,7 @@ void assign_resources(struct bus *bus)
 		curdev->ops->set_resources(curdev);
 	}
 	printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
-		    dev_path(bus->dev), bus->secondary, bus->link);
+		    dev_path(bus->dev), bus->secondary, bus->link_num);
 }
 
 /**
@@ -846,12 +853,12 @@ unsigned int scan_bus(struct device *bus
 
 	do_scan_bus = 1;
 	while (do_scan_bus) {
-		int link;
+		struct bus *link;
 		new_max = busdev->ops->scan_bus(busdev, max);
 		do_scan_bus = 0;
-		for (link = 0; link < busdev->links; link++) {
-			if (busdev->link[link].reset_needed) {
-				if (reset_bus(&busdev->link[link])) {
+		for (link = busdev->link_list; link; link = link->next) {
+			if (link->reset_needed) {
+				if (reset_bus(link)) {
 					do_scan_bus = 1;
 				} else {
 					busdev->bus->reset_needed = 1;
@@ -940,30 +947,30 @@ void dev_configure(void)
 	/* Read the resources for the entire tree. */
 
 	printk(BIOS_INFO, "Reading resources...\n");
-	read_resources(&root->link[0]);
+	read_resources(root->link_list);
 	printk(BIOS_INFO, "Done reading resources.\n");
 
 	print_resource_tree(root, BIOS_SPEW, "After reading.");
 
 	/* Compute resources for all domains. */
-	for (child = root->link[0].children; child; child = child->sibling) {
+	for (child = root->link_list->children; child; child = child->sibling) {
 		if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
 			continue;
 		for (res = child->resource_list; res; res = res->next) {
 			if (res->flags & IORESOURCE_FIXED)
 				continue;
 			if (res->flags & IORESOURCE_PREFETCH) {
-				compute_resources(&child->link[0],
+				compute_resources(child->link_list,
 					       res, MEM_MASK, PREF_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_MEM) {
-				compute_resources(&child->link[0],
+				compute_resources(child->link_list,
 					       res, MEM_MASK, MEM_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_IO) {
-				compute_resources(&child->link[0],
+				compute_resources(child->link_list,
 					       res, IO_MASK, IO_TYPE);
 				continue;
 			}
@@ -971,14 +978,14 @@ void dev_configure(void)
 	}
 
 	/* For all domains. */
-	for (child = root->link[0].children; child; child=child->sibling)
+	for (child = root->link_list->children; child; child=child->sibling)
 		if (child->path.type == DEVICE_PATH_PCI_DOMAIN)
 			avoid_fixed_resources(child);
 
 	/* Now we need to adjust the resources. MEM resources need to start at
 	 * the highest address managable.
 	 */
-	for (child = root->link[0].children; child; child = child->sibling) {
+	for (child = root->link_list->children; child; child = child->sibling) {
 		if (child->path.type != DEVICE_PATH_PCI_DOMAIN)
 			continue;
 		for (res = child->resource_list; res; res = res->next) {
@@ -991,30 +998,30 @@ void dev_configure(void)
 
 	/* Store the computed resource allocations into device registers ... */
 	printk(BIOS_INFO, "Setting resources...\n");
-	for (child = root->link[0].children; child; child = child->sibling) {
+	for (child = root->link_list->children; child; child = child->sibling) {
 		if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
 			continue;
 		for (res = child->resource_list; res; res = res->next) {
 			if (res->flags & IORESOURCE_FIXED)
 				continue;
 			if (res->flags & IORESOURCE_PREFETCH) {
-				allocate_resources(&child->link[0],
+				allocate_resources(child->link_list,
 					       res, MEM_MASK, PREF_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_MEM) {
-				allocate_resources(&child->link[0],
+				allocate_resources(child->link_list,
 					       res, MEM_MASK, MEM_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_IO) {
-				allocate_resources(&child->link[0],
+				allocate_resources(child->link_list,
 					       res, IO_MASK, IO_TYPE);
 				continue;
 			}
 		}
 	}
-	assign_resources(&root->link[0]);
+	assign_resources(root->link_list);
 	printk(BIOS_INFO, "Done setting resources.\n");
 	print_resource_tree(root, BIOS_SPEW, "After assigning values.");
 
@@ -1055,7 +1062,7 @@ void dev_initialize(void)
 			if (dev->path.type == DEVICE_PATH_I2C) {
 				printk(BIOS_DEBUG, "smbus: %s[%d]->",
 					     dev_path(dev->bus->dev),
-					     dev->bus->link);
+					     dev->bus->link_num);
 			}
 			printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
 			dev->initialized = 1;
Index: svn/src/cpu/amd/sc520/sc520.c
===================================================================
--- svn.orig/src/cpu/amd/sc520/sc520.c
+++ svn/src/cpu/amd/sc520/sc520.c
@@ -130,8 +130,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
         uint32_t pci_tolm;
   printk(BIOS_SPEW, "%s\n", __func__);
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned long tomk, tolmk;
 		//		unsigned char rambits;
@@ -168,7 +168,7 @@ static void pci_domain_set_resources(dev
 		idx = 10;
 		ram_resource(dev, idx++, 0, tolmk);
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 #if 0
Index: svn/src/devices/cardbus_device.c
===================================================================
--- svn.orig/src/devices/cardbus_device.c
+++ svn/src/devices/cardbus_device.c
@@ -158,7 +158,7 @@ void cardbus_enable_resources(device_t d
 {
 	uint16_t ctrl;
 	ctrl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL);
-	ctrl |= (dev->link[0].bridge_ctrl & (
+	ctrl |= (dev->link_list->bridge_ctrl & (
 			PCI_BRIDGE_CTL_PARITY |
 			PCI_BRIDGE_CTL_SERR |
 			PCI_BRIDGE_CTL_NO_ISA |
@@ -178,8 +178,8 @@ struct device_operations default_cardbus
 	.read_resources   = cardbus_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = cardbus_enable_resources,
-	.init		  = 0,
-	.scan_bus	  = pci_scan_bridge,
+	.init			  = 0,
+	.scan_bus		  = pci_scan_bridge,
 	.enable           = 0,
 	.reset_bus        = pci_bus_reset,
 };
Index: svn/src/devices/oprom/yabel/device.c
===================================================================
--- svn.orig/src/devices/oprom/yabel/device.c
+++ svn/src/devices/oprom/yabel/device.c
@@ -45,7 +45,7 @@ biosemu_dev_get_addr_info(void)
 {
 	int taa_index = 0;
 	struct resource *r;
-	u8 bus = bios_device.dev->bus->link;
+	u8 bus = bios_device.dev->bus->link_num;
 	u16 devfn = bios_device.dev->path.pci.devfn;
 
 	bios_device.bus =  bus;
Index: svn/src/devices/pci_device.c
===================================================================
--- svn.orig/src/devices/pci_device.c
+++ svn/src/devices/pci_device.c
@@ -551,15 +551,13 @@ static void pci_set_resource(struct devi
 void pci_dev_set_resources(struct device *dev)
 {
 	struct resource *res;
-	unsigned link;
+	struct bus *bus;
 	u8 line;
 
 	for (res = dev->resource_list; res; res = res->next) {
 		pci_set_resource(dev, res);
 	}
-	for (link = 0; link < dev->links; link++) {
-		struct bus *bus;
-		bus = &dev->link[link];
+	for (bus = dev->link_list; bus; bus = bus->next) {
 		if (bus->children) {
 			assign_resources(bus);
 		}
@@ -614,10 +612,10 @@ void pci_bus_enable_resources(struct dev
 	/* Enable I/O in command register if there is VGA card
 	 * connected with (even it does not claim I/O resource).
 	 */
-	if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
+	if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
 		dev->command |= PCI_COMMAND_IO;
 	ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
-	ctrl |= dev->link[0].bridge_ctrl;
+	ctrl |= dev->link_list->bridge_ctrl;
 	ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR);	/* Error check. */
 	printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
 	pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
@@ -1102,9 +1100,17 @@ unsigned int do_pci_scan_bridge(struct d
 
 	printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(dev));
 
-	bus = &dev->link[0];
-	bus->dev = dev;
-	dev->links = 1;
+	if (dev->link_list == NULL) {
+		struct bus *link;
+		link = malloc(sizeof(*link));
+		if (link == NULL)
+			die("Couldn't allocate a link!\n");
+		memset(link, 0, sizeof(*link));
+		link->dev = dev;
+		dev->link_list = link;
+	}
+
+	bus = dev->link_list;
 
 	/* Set up the primary, secondary and subordinate bus numbers. We have
 	 * no idea how many buses are behind this bridge yet, so we set the
@@ -1179,7 +1185,7 @@ unsigned int pci_scan_bridge(struct devi
  */
 unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
 {
-	max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+	max = pci_scan_bus(dev->link_list, PCI_DEVFN(0, 0), 0xff, max);
 	return max;
 }
 
Index: svn/src/devices/pcix_device.c
===================================================================
--- svn.orig/src/devices/pcix_device.c
+++ svn/src/devices/pcix_device.c
@@ -61,20 +61,11 @@ static void pcix_tune_dev(device_t dev)
 	}
 }
 
-unsigned int pcix_scan_bus(struct bus *bus,
-	unsigned min_devfn, unsigned max_devfn, unsigned int max)
+static void pcix_tune_bus(struct bus *bus)
 {
 	device_t child;
-	max = pci_scan_bus(bus, min_devfn, max_devfn, max);
-	for(child = bus->children; child; child = child->sibling) {
-		if (	(child->path.pci.devfn < min_devfn) ||
-			(child->path.pci.devfn > max_devfn))
-		{
-			continue;
-		}
+	for(child = bus->children; child; child = child->sibling)
 		pcix_tune_dev(child);
-	}
-	return max;
 }
 
 const char *pcix_speed(unsigned sstatus)
@@ -124,18 +115,17 @@ unsigned int pcix_scan_bridge(device_t d
 	unsigned pos;
 	unsigned sstatus;
 
+	max = do_pci_scan_bridge(dev, max, pci_scan_bus);
 	/* Find the PCI-X capability */
 	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 	sstatus = pci_read_config16(dev, pos + PCI_X_SEC_STATUS);
 
-	if (PCI_X_SSTATUS_MFREQ(sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
-		max = do_pci_scan_bridge(dev, max, pci_scan_bus);
-	} else {
-		max = do_pci_scan_bridge(dev, max, pcix_scan_bus);
+	if (PCI_X_SSTATUS_MFREQ(sstatus) != PCI_X_SSTATUS_CONVENTIONAL_PCI) {
+		pcix_tune_bus(dev->link_list);
 	}
 
 	/* Print the PCI-X bus speed */
-	printk(BIOS_DEBUG, "PCI: %02x: %s\n", dev->link[0].secondary, pcix_speed(sstatus));
+	printk(BIOS_DEBUG, "PCI: %02x: %s\n", dev->link_list->secondary, pcix_speed(sstatus));
 
 	return max;
 }
Index: svn/src/devices/root_device.c
===================================================================
--- svn.orig/src/devices/root_device.c
+++ svn/src/devices/root_device.c
@@ -75,17 +75,17 @@ static int smbus_max = 0;
 unsigned int scan_static_bus(device_t bus, unsigned int max)
 {
 	device_t child;
-	unsigned link;
+	struct bus* link;
 
 	printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(bus));
 
-	for(link = 0; link < bus->links; link++) {
+	for(link = bus->link_list; link; link = link->next) {
 		/* for smbus bus enumerate */
-		child = bus->link[link].children;
+		child = link->children;
 		if(child && child->path.type == DEVICE_PATH_I2C) {
-			bus->link[link].secondary = ++smbus_max;
+			link->secondary = ++smbus_max;
 		}
-		for(child = bus->link[link].children; child; child = child->sibling) {
+		for(child =link->children; child; child = child->sibling) {
 			if (child->chip_ops && child->chip_ops->enable_dev) {
 				child->chip_ops->enable_dev(child);
 			}
@@ -94,15 +94,15 @@ unsigned int scan_static_bus(device_t bu
 			}
  			if (child->path.type == DEVICE_PATH_I2C) {
  				printk(BIOS_DEBUG, "smbus: %s[%d]->",
-					dev_path(child->bus->dev), child->bus->link );
+					dev_path(child->bus->dev), child->bus->link_num );
 			}
 			printk(BIOS_DEBUG, "%s %s\n",
 				dev_path(child),
 				child->enabled?"enabled": "disabled");
 		}
 	}
-	for(link = 0; link < bus->links; link++) {
-		for(child = bus->link[link].children; child; child = child->sibling) {
+	for(link = bus->link_list; link; link = link->next) {
+		for(child = link->children; child; child = child->sibling) {
 			if (!child->ops || !child->ops->scan_bus)
 				continue;
 			printk(BIOS_SPEW, "%s scanning...\n", dev_path(child));
@@ -130,10 +130,10 @@ unsigned int scan_static_bus(device_t bu
  */
 void enable_childrens_resources(device_t dev)
 {
-	unsigned link;
-	for(link = 0; link < dev->links; link++) {
+	struct bus *link;
+	for(link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for(child = dev->link[link].children; child; child = child->sibling) {
+		for(child = link->children; child; child = child->sibling) {
 			enable_resources(child);
 		}
 	}
Index: svn/src/devices/smbus_ops.c
===================================================================
--- svn.orig/src/devices/smbus_ops.c
+++ svn/src/devices/smbus_ops.c
@@ -58,7 +58,7 @@ int smbus_set_link(device_t dev)
 //		printk(BIOS_INFO, " %s[%d] -> ", dev_path(pbus_a[i]->dev), pbus_a[i]->link);
         	if (ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) {
                 	if (pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link)
-                        	pbus_a[i]->dev->ops->set_link(pbus_a[i]->dev, pbus_a[i]->link);
+                        	pbus_a[i]->dev->ops->set_link(pbus_a[i]->dev, pbus_a[i]->link_num);
 		}
 	}
 //	printk(BIOS_INFO, " %s\n", dev_path(dev));
Index: svn/src/devices/device_util.c
===================================================================
--- svn.orig/src/devices/device_util.c
+++ svn/src/devices/device_util.c
@@ -40,7 +40,7 @@
 device_t find_dev_path(struct bus *parent, struct device_path *path)
 {
 	device_t child;
-	for(child = parent->children; child; child = child->sibling) {
+	for (child = parent->children; child; child = child->sibling) {
 		if (path_eq(path, &child->path)) {
 			break;
 		}
@@ -213,7 +213,7 @@ const char *dev_path(device_t dev)
 const char *bus_path(struct bus *bus)
 {
 	static char buffer[BUS_PATH_MAX];
-	sprintf(buffer, "%s,%d", dev_path(bus->dev), bus->link);
+	sprintf(buffer, "%s,%d", dev_path(bus->dev), bus->link_num);
 	return buffer;
 }
 
@@ -303,7 +303,7 @@ void compact_resources(device_t dev)
 {
 	struct resource *res, *next, *prev = NULL;
 	/* Move all of the free resources to the end */
-	for(res = dev->resource_list; res; res = next) {
+	for (res = dev->resource_list; res; res = next) {
 		next = res->next;
 		if (!res->flags)
 			free_resource(dev, res, prev);
@@ -323,7 +323,7 @@ struct resource *probe_resource(device_t
 {
 	struct resource *res;
 	/* See if there is a resource with the appropriate index */
-	for(res = dev->resource_list; res; res = res->next) {
+	for (res = dev->resource_list; res; res = res->next) {
 		if (res->index == index)
 			break;
 	}
@@ -496,9 +496,9 @@ void report_resource_stored(device_t dev
 		buf[0] = '\0';
 		if (resource->flags & IORESOURCE_PCI_BRIDGE) {
 #if CONFIG_PCI_BUS_SEGN_BITS
-			sprintf(buf, "bus %04x:%02x ", dev->bus->secondary>>8, dev->link[0].secondary & 0xff);
+			sprintf(buf, "bus %04x:%02x ", dev->bus->secondary>>8, dev->link_list->secondary & 0xff);
 #else
-			sprintf(buf, "bus %02x ", dev->link[0].secondary);
+			sprintf(buf, "bus %02x ", dev->link_list->secondary);
 #endif
 		}
 		printk(BIOS_DEBUG,
@@ -518,11 +518,11 @@ void search_bus_resources(struct bus *bu
 	resource_search_t search, void *gp)
 {
 	struct device *curdev;
-	for(curdev = bus->children; curdev; curdev = curdev->sibling) {
+	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
 		struct resource *res;
 		/* Ignore disabled devices */
 		if (!curdev->enabled) continue;
-		for(res = curdev->resource_list; res; res = res->next) {
+		for (res = curdev->resource_list; res; res = res->next) {
 			/* If it isn't the right kind of resource ignore it */
 			if ((res->flags & type_mask) != type) {
 				continue;
@@ -530,7 +530,9 @@ void search_bus_resources(struct bus *bu
 			/* If it is a subtractive resource recurse */
 			if (res->flags & IORESOURCE_SUBTRACTIVE) {
 				struct bus * subbus;
-				subbus = &curdev->link[IOINDEX_SUBTRACTIVE_LINK(res->index)];
+				for (subbus = curdev->link_list; subbus; subbus = subbus->next)
+					if (subbus->link_num == IOINDEX_SUBTRACTIVE_LINK(res->index))
+						break;
 				search_bus_resources(subbus, type_mask, type, search, gp);
 				continue;
 			}
@@ -544,11 +546,11 @@ void search_global_resources(
 	resource_search_t search, void *gp)
 {
 	struct device *curdev;
-	for(curdev = all_devices; curdev; curdev = curdev->next) {
+	for (curdev = all_devices; curdev; curdev = curdev->next) {
 		struct resource *res;
 		/* Ignore disabled devices */
 		if (!curdev->enabled) continue;
-		for(res = curdev->resource_list; res; res = res->next) {
+		for (res = curdev->resource_list; res; res = res->next) {
 			/* If it isn't the right kind of resource ignore it */
 			if ((res->flags & type_mask) != type) {
 				continue;
@@ -579,10 +581,10 @@ void dev_set_enabled(device_t dev, int e
 void disable_children(struct bus *bus)
 {
 	device_t child;
-	for(child = bus->children; child; child = child->sibling) {
-		int link;
-		for(link = 0; link < child->links; link++) {
-			disable_children(&child->link[link]);
+	for (child = bus->children; child; child = child->sibling) {
+		struct bus *link;
+		for (link = child->link_list; link; link = link->next) {
+			disable_children(link);
 		}
 		dev_set_enabled(child, 0);
 	}
@@ -590,8 +592,9 @@ void disable_children(struct bus *bus)
 
 static void resource_tree(struct device *root, int debug_level, int depth)
 {
-	int i = 0, link = 0;
+	int i = 0;
 	struct device *child;
+	struct bus *link;
 	struct resource *res;
 	char indent[30];	/* If your tree has more levels, it's wrong. */
 
@@ -599,10 +602,12 @@ static void resource_tree(struct device 
 		indent[i] = ' ';
 	indent[i] = '\0';
 
-	do_printk(debug_level, "%s%s links %x child on link 0", indent,
-		  dev_path(root), root->links);
-	do_printk(debug_level, " %s\n", root->link[0].children ?
-		  dev_path(root->link[0].children) : "NULL");
+ 	do_printk(BIOS_DEBUG, "%s%s", indent, dev_path(root));
+ 	if (root->link_list && root->link_list->children)
+ 		do_printk(BIOS_DEBUG, " child on link 0 %s",
+ 			  dev_path(root->link_list->children));
+ 	do_printk(BIOS_DEBUG, "\n");
+
 	for (res = root->resource_list; res; res = res->next) {
 		do_printk(debug_level,
 			  "%s%s resource base %llx size %llx align %d gran %d limit %llx flags %lx index %lx\n",
@@ -612,9 +617,8 @@ static void resource_tree(struct device 
 			  res->flags, res->index);
 	}
 
-	for (link = 0; link < root->links; link++) {
-		for (child = root->link[link].children; child;
-		     child = child->sibling)
+	for (link = root->link_list; link; link = link->next) {
+		for (child = link->children; child; child = child->sibling)
 			resource_tree(child, debug_level, depth + 1);
 	}
 }
@@ -640,13 +644,15 @@ void show_devs_tree(struct device *dev, 
 	char depth_str[20] = "";
 	int i;
 	struct device *sibling;
+	struct bus *link;
+
 	for (i = 0; i < depth; i++)
 		depth_str[i] = ' ';
 	depth_str[i] = '\0';
 	do_printk(debug_level, "%s%s: enabled %d\n",
 		  depth_str, dev_path(dev), dev->enabled);
-	for (i = 0; i < dev->links; i++) {
-		for (sibling = dev->link[i].children; sibling;
+	for (link = dev->link_list; link; link = link->next) {
+		for (sibling = link->children; sibling;
 		     sibling = sibling->sibling)
 			show_devs_tree(sibling, debug_level, depth + 1, i);
 	}
Index: svn/src/arch/i386/boot/mpspec.c
===================================================================
--- svn.orig/src/arch/i386/boot/mpspec.c
+++ svn/src/arch/i386/boot/mpspec.c
@@ -190,7 +190,6 @@ void smp_write_intsrc_pci_bridge(struct 
 {
 	struct device *child;
 
-	int linkn;
 	int i;
 	int srcbus;
 	int slot;
@@ -198,9 +197,8 @@ void smp_write_intsrc_pci_bridge(struct 
 	struct bus *link;
 	unsigned char dstirq_x[4];
 
-	for (linkn = 0; linkn < dev->links; linkn++) {
+	for (link = dev->link_list; link; link = link->next) {
 
-		link = &dev->link[linkn];
 		child = link->children;
 		srcbus = link->secondary;
 
Index: svn/src/drivers/generic/debug/debug_dev.c
===================================================================
--- svn.orig/src/drivers/generic/debug/debug_dev.c
+++ svn/src/drivers/generic/debug/debug_dev.c
@@ -85,7 +85,7 @@ static void print_cpuid(void)
 static void print_smbus_regs(struct device *dev)
 {
 	int j;
-	printk(BIOS_DEBUG, "smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link);
+	printk(BIOS_DEBUG, "smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link_num);
 	printk(BIOS_DEBUG, "%s", dev_path(dev));
 	for(j = 0; j < 256; j++) {
 		int status;
@@ -107,22 +107,22 @@ static void print_smbus_regs(struct devi
 static void print_smbus_regs_all(struct device *dev)
 {
 	struct device *child;
-	int i;
+	struct bus *link;
 	if (dev->enabled && dev->path.type == DEVICE_PATH_I2C)
 	{
 		// Here don't need to call smbus_set_link, because we scan it from top to down
 		if( dev->bus->dev->path.type == DEVICE_PATH_I2C) { // it's under i2c MUX so set mux at first
 			if(ops_smbus_bus(get_pbus_smbus(dev->bus->dev))) {
 				if(dev->bus->dev->ops && dev->bus->dev->ops->set_link)
-					dev->bus->dev->ops->set_link(dev->bus->dev, dev->bus->link);
+					dev->bus->dev->ops->set_link(dev->bus->dev, dev->bus->link_num);
 			}
 		}
 
 		if(ops_smbus_bus(get_pbus_smbus(dev))) print_smbus_regs(dev);
 	}
 
-	for(i=0; i< dev->links; i++) {
-		for (child = dev->link[i].children; child; child = child->sibling) {
+	for(link = dev->link_list; link; link = link->next) {
+		for (child = link->children; child; child = child->sibling) {
 			print_smbus_regs_all(child);
         	}
 	}
Index: svn/src/drivers/i2c/i2cmux/i2cmux.c
===================================================================
--- svn.orig/src/drivers/i2c/i2cmux/i2cmux.c
+++ svn/src/drivers/i2c/i2cmux/i2cmux.c
@@ -34,7 +34,7 @@ static struct device_operations i2cmux_o
 
 static void enable_dev(struct device *dev)
 {
-	if(dev->links>0)
+	if(dev->link_list != NULL)
 		dev->ops = &i2cmux_operations;
 }
 
Index: svn/src/drivers/i2c/i2cmux2/i2cmux2.c
===================================================================
--- svn.orig/src/drivers/i2c/i2cmux2/i2cmux2.c
+++ svn/src/drivers/i2c/i2cmux2/i2cmux2.c
@@ -33,7 +33,7 @@ static struct device_operations i2cmux2_
 
 static void enable_dev(struct device *dev)
 {
-	if(dev->links>0)
+	if(dev->link_list != NULL)
 		dev->ops = &i2cmux2_operations;
 }
 
Index: svn/src/mainboard/emulation/qemu-x86/northbridge.c
===================================================================
--- svn.orig/src/mainboard/emulation/qemu-x86/northbridge.c
+++ svn/src/mainboard/emulation/qemu-x86/northbridge.c
@@ -60,7 +60,7 @@ extern uint64_t high_tables_base, high_t
 
 static void cpu_pci_domain_set_resources(device_t dev)
 {
-	u32 pci_tolm = find_pci_tolm(&dev->link[0]);
+	u32 pci_tolm = find_pci_tolm(dev->link_list);
 	unsigned long tomk = 0, tolmk;
 	int idx;
 
@@ -91,7 +91,7 @@ static void cpu_pci_domain_set_resources
 	high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static void cpu_pci_domain_read_resources(struct device *dev)
Index: svn/src/mainboard/kontron/986lcd-m/mptable.c
===================================================================
--- svn.orig/src/mainboard/kontron/986lcd-m/mptable.c
+++ svn/src/mainboard/kontron/986lcd-m/mptable.c
@@ -70,7 +70,7 @@ static void *smp_write_config_table(void
 	if (!riser)
 		riser = dev_find_device(0x3388, 0x0022, 0);
 	if (riser) {
-		riser_bus = riser->link[0].secondary;
+		riser_bus = riser->link_list->secondary;
 		printk(BIOS_SPEW, "Riser bus is %x\n", riser_bus);
 		max_pci_bus = riser_bus;
 	}
Index: svn/src/mainboard/tyan/s2881/mainboard.c
===================================================================
--- svn.orig/src/mainboard/tyan/s2881/mainboard.c
+++ svn/src/mainboard/tyan/s2881/mainboard.c
@@ -46,7 +46,7 @@ static void adt7463_init(device_t dev)
 	/* Find the ADT7463 device. */
 	path.type = DEVICE_PATH_I2C;
 	path.i2c.device = 0x2d;
-	adt7463 = find_dev_path(smbus_dev->link, &path);
+	adt7463 = find_dev_path(smbus_dev->link_list, &path);
 	if (!adt7463)
 		die("ADT7463 not found\n");
 	printk(BIOS_DEBUG, "ADT7463 found\n");
@@ -113,7 +113,6 @@ static unsigned int scan_root_bus(device
 {
 	struct device_path path;
 	device_t dummy;
-	unsigned link_i;
 
 	max = root_dev_scan_bus(root, max);
 
@@ -126,20 +125,10 @@ static unsigned int scan_root_bus(device
 	 * as the last device to be initialized.
 	 */
 
-	link_i = root->links;
-	if (link_i >= MAX_LINKS) {
-		printk(BIOS_DEBUG, "Reached MAX_LINKS, not configuring ADT7463");
-		return max;
-	}
-	root->link[link_i].link = link_i;
-	root->link[link_i].dev = root;
-	root->link[link_i].children = 0;
-	root->links++;
-
 	path.type = DEVICE_PATH_PNP;
 	path.pnp.port = 0;
 	path.pnp.device = 0;
-	dummy = alloc_dev(&root->link[link_i], &path);
+	dummy = alloc_dev(root->link_list, &path);
 	dummy->ops = &dummy_operations;
 
 	return max;
Index: svn/src/northbridge/amd/amdfam10/northbridge.c
===================================================================
--- svn.orig/src/northbridge/amd/amdfam10/northbridge.c
+++ svn/src/northbridge/amd/amdfam10/northbridge.c
@@ -137,7 +137,7 @@ static void set_vga_enable_reg(u32 nodei
 
 }
 
-static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink,
+static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, u32 link_num, u32 sblink,
 				u32 max, u32 offset_unitid)
 {
 //	I want to put sb chain in bus 0 can I?
@@ -149,7 +149,7 @@ static u32 amdfam10_scan_chain(device_t 
 		u32 ht_unitid_base[4]; // here assume only 4 HT device on chain
 		u32 max_bus;
 		u32 min_bus;
-		u32 is_sublink1 = (link>3);
+		u32 is_sublink1 = (link_num>3);
 		device_t devx;
 		u32 busses;
 		u32 segn = max>>8;
@@ -162,7 +162,7 @@ static u32 amdfam10_scan_chain(device_t 
 		if(is_sublink1) {
 			u32 regpos;
 			u32 reg;
-			regpos = 0x170 + 4 * (link&3); // it is only on sublink0
+			regpos = 0x170 + 4 * (link_num&3); // it is only on sublink0
 			reg = pci_read_config32(dev, regpos);
 			if(reg & 1) return max; // already ganged no sblink1
 			devx = get_node_pci(nodeid, 4);
@@ -171,15 +171,15 @@ static u32 amdfam10_scan_chain(device_t 
 			devx = dev;
 
 
-		dev->link[link].cap = 0x80 + ((link&3) *0x20);
+		link->cap = 0x80 + ((link_num&3) *0x20);
 		do {
-			link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
+			link_type = pci_read_config32(devx, link->cap + 0x18);
 		} while(link_type & ConnectionPending);
 		if (!(link_type & LinkConnected)) {
 			return max;
 		}
 		do {
-			link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
+			link_type = pci_read_config32(devx, link->cap + 0x18);
 		} while(!(link_type & InitComplete));
 		if (!(link_type & NonCoherent)) {
 			return max;
@@ -187,7 +187,7 @@ static u32 amdfam10_scan_chain(device_t 
 		/* See if there is an available configuration space mapping
 		 * register in function 1.
 		 */
-		ht_c_index = get_ht_c_index(nodeid, link, &sysconf);
+		ht_c_index = get_ht_c_index(nodeid, link_num, &sysconf);
 
 #if CONFIG_EXT_CONF_SUPPORT == 0
 		if(ht_c_index>=4) return max;
@@ -199,7 +199,7 @@ static u32 amdfam10_scan_chain(device_t 
 		 */
 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
 		// first chain will on bus 0
-		if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
+		if((nodeid == 0) && (sblink==link_num)) { // actually max is 0 here
 			min_bus = max;
 		}
 	#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
@@ -221,26 +221,26 @@ static u32 amdfam10_scan_chain(device_t 
 #endif
 		max_bus = 0xfc | (segn<<8);
 
-		dev->link[link].secondary = min_bus;
-		dev->link[link].subordinate = max_bus;
+		link->secondary = min_bus;
+		link->subordinate = max_bus;
 
 		/* Read the existing primary/secondary/subordinate bus
 		 * number configuration.
 		 */
-		busses = pci_read_config32(devx, dev->link[link].cap + 0x14);
+		busses = pci_read_config32(devx, link->cap + 0x14);
 
 		/* Configure the bus numbers for this bridge: the configuration
 		 * transactions will not be propagates by the bridge if it is
 		 * not correctly configured
 		 */
 		busses &= 0xffff00ff;
-		busses |= ((u32)(dev->link[link].secondary) << 8);
-		pci_write_config32(devx, dev->link[link].cap + 0x14, busses);
+		busses |= ((u32)(link->secondary) << 8);
+		pci_write_config32(devx, link->cap + 0x14, busses);
 
 
 		/* set the config map space */
 
-		set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
+		set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes);
 
 		/* Now we can scan all of the subordinate busses i.e. the
 		 * chain on the hypertranport link
@@ -255,17 +255,17 @@ static u32 amdfam10_scan_chain(device_t 
 		else
 			max_devfn = (0x1f<<3) | 7;
 
-		max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
+		max = hypertransport_scan_chain(link, 0, max_devfn, max, ht_unitid_base, offset_unitid);
 
 		/* We know the number of busses behind this bridge.  Set the
 		 * subordinate bus number to it's real value
 		 */
 		if(ht_c_index>3) { // clear the extend reg
-			clear_config_map_reg(nodeid, link, ht_c_index, (max+1)>>sysconf.segbit, (dev->link[link].subordinate)>>sysconf.segbit, sysconf.nodes);
+			clear_config_map_reg(nodeid, link_num, ht_c_index, (max+1)>>sysconf.segbit, (link->subordinate)>>sysconf.segbit, sysconf.nodes);
 		}
 
-		dev->link[link].subordinate = max;
-		set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
+		link->subordinate = max;
+		set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes);
 		sysconf.ht_c_num++;
 
 		{
@@ -278,14 +278,14 @@ static u32 amdfam10_scan_chain(device_t 
 			sysconf.hcdn_reg[ht_c_index] = temp;
 
 		}
-	store_ht_c_conf_bus(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, &sysconf);
+	store_ht_c_conf_bus(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, &sysconf);
 	return max;
 }
 
-static u32 amdfam10_scan_chains(device_t dev, u32 max)
+static unsigned amdfam10_scan_chains(device_t dev, unsigned max)
 {
 	unsigned nodeid;
-	u32 link;
+	struct bus *link;
 	unsigned sblink = sysconf.sblk;
 	unsigned offset_unitid = 0;
 
@@ -297,7 +297,9 @@ static u32 amdfam10_scan_chains(device_t
 	#if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 		offset_unitid = 1;
 	#endif
-		max = amdfam10_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
+		for (link = dev->link_list; link; link = link->next)
+			if (link->link_num == sblink)
+				max = amdfam10_scan_chain(dev, nodeid, link, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
 	}
 #endif
 
@@ -305,19 +307,19 @@ static u32 amdfam10_scan_chains(device_t
 	max = check_segn(dev, max, sysconf.nodes, &sysconf);
 #endif
 
-	for(link = 0; link < dev->links; link++) {
+	for(link = dev->link_list; link; link = link->next) {
 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
-		if( (nodeid == 0) && (sblink == link) ) continue; //already done
+		if( (nodeid == 0) && (sblink == link->link_num) ) continue; //already done
 #endif
 		offset_unitid = 0;
 		#if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 			#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
-			if((nodeid == 0) && (sblink == link))
+			if((nodeid == 0) && (sblink == link->link_num))
 			#endif
 				offset_unitid = 1;
 		#endif
 
-		max = amdfam10_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
+		max = amdfam10_scan_chain(dev, nodeid, link, link->link_num, sblink, max, offset_unitid);
 	}
 	return max;
 }
@@ -482,12 +484,12 @@ static void amdfam10_link_read_bases(dev
 
 static void amdfam10_read_resources(device_t dev)
 {
-	u32 nodeid, link;
-
+	u32 nodeid;
+	struct bus *link;
 	nodeid = amdfam10_nodeid(dev);
-	for(link = 0; link < dev->links; link++) {
-		if (dev->link[link].children) {
-			amdfam10_link_read_bases(dev, nodeid, link);
+	for(link = dev->link_list; link; link = link->next) {
+		if (link->children) {
+			amdfam10_link_read_bases(dev, nodeid, link->link_num);
 		}
 	}
 }
@@ -496,7 +498,7 @@ static void amdfam10_set_resource(device
 				u32 nodeid)
 {
 	resource_t rbase, rend;
-	unsigned reg, link;
+	unsigned reg, link_num;
 	char buf[50];
 
 	/* Make certain the resource has actually been set */
@@ -525,20 +527,20 @@ static void amdfam10_set_resource(device
 
 	/* Get the register and link */
 	reg  = resource->index & 0xfff; // 4k
-	link = IOINDEX_LINK(resource->index);
+	link_num = IOINDEX_LINK(resource->index);
 
 	if (resource->flags & IORESOURCE_IO) {
 
-		set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
-		store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
+		set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
+		store_conf_io_addr(nodeid, link_num, reg, (resource->index >> 24), rbase>>8, rend>>8);
 	}
 	else if (resource->flags & IORESOURCE_MEM) {
-		set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
-		store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
+		set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
+		store_conf_mmio_addr(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8);
 	}
 	resource->flags |= IORESOURCE_STORED;
-	sprintf(buf, " <node %02x link %02x>",
-		nodeid, link);
+	sprintf(buf, " <node %x link %x>",
+		nodeid, link_num);
 	report_resource_stored(dev, resource, buf);
 }
 
@@ -553,18 +555,18 @@ extern device_t vga_pri;	// the primary 
 
 static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid)
 {
-	unsigned link;
+	struct bus *link;
 
 	/* find out which link the VGA card is connected,
 	 * we only deal with the 'first' vga card */
-	for (link = 0; link < dev->links; link++) {
-		if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
+	for (link = dev->link_list; link; link = link->next) {
+		if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 #if CONFIG_CONSOLE_VGA_MULTI == 1
-			printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
-				dev->link[link].secondary,dev->link[link].subordinate);
+			printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary,
+				link->secondary,link->subordinate);
 			/* We need to make sure the vga_pri is under the link */
-			if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
-				(vga_pri->bus->secondary <= dev->link[link].subordinate )
+			if((vga_pri->bus->secondary >= link->secondary ) &&
+				(vga_pri->bus->secondary <= link->subordinate )
 			)
 #endif
 			break;
@@ -572,16 +574,17 @@ static void amdfam10_create_vga_resource
 	}
 
 	/* no VGA card installed */
-	if (link == dev->links)
+	if (link == NULL)
 		return;
 
-	printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
-	set_vga_enable_reg(nodeid, link);
+	printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link->link_num);
+	set_vga_enable_reg(nodeid, link->link_num);
 }
 
 static void amdfam10_set_resources(device_t dev)
 {
-	u32 nodeid, link;
+	unsigned nodeid;
+	struct bus *bus;
 	struct resource *res;
 
 	/* Find the nodeid */
@@ -594,9 +597,7 @@ static void amdfam10_set_resources(devic
 		amdfam10_set_resource(dev, res, nodeid);
 	}
 
-	for(link = 0; link < dev->links; link++) {
-		struct bus *bus;
-		bus = &dev->link[link];
+	for(bus = dev->link_list; bus; bus = bus->next) {
 		if (bus->children) {
 			assign_resources(bus);
 		}
@@ -672,22 +673,22 @@ static void amdfam10_domain_read_resourc
 #if CONFIG_PCI_64BIT_PREF_MEM == 0
 	pci_domain_read_resources(dev);
 #else
-	unsigned link;
+	struct bus *link;
 	struct resource *resource;
-	for(link=0; link<dev->links; link++) {
+	for(link=dev->link_list; link; link = link->next) {
 		/* Initialize the system wide io space constraints */
-		resource = new_resource(dev, 0|(link<<2));
+		resource = new_resource(dev, 0|(link->link_num<<2));
 		resource->base	= 0x400;
 		resource->limit = 0xffffUL;
 		resource->flags = IORESOURCE_IO;
 
 		/* Initialize the system wide prefetchable memory resources constraints */
-		resource = new_resource(dev, 1|(link<<2));
+		resource = new_resource(dev, 1|(link->link_num<<2));
 		resource->limit = 0xfcffffffffULL;
 		resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
 
 		/* Initialize the system wide memory resources constraints */
-		resource = new_resource(dev, 2|(link<<2));
+		resource = new_resource(dev, 2|(link->link_num<<2));
 		resource->limit = 0xfcffffffffULL;
 		resource->flags = IORESOURCE_MEM;
 	}
@@ -881,7 +882,7 @@ static void amdfam10_domain_set_resource
 	unsigned long mmio_basek;
 	u32 pci_tolm;
 	int i, idx;
-	u32 link;
+	struct bus *link;
 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
 	struct hw_mem_hole_info mem_hole;
 	u32 reset_memhole = 1;
@@ -889,12 +890,12 @@ static void amdfam10_domain_set_resource
 
 #if CONFIG_PCI_64BIT_PREF_MEM == 1
 
-	for(link = 0; link < dev->links; link++) {
+	for(link = dev->link_list; link; link = link->next) {
 		/* Now reallocate the pci resources memory with the
 		 * highest addresses I can manage.
 		 */
-		mem1 = find_resource(dev, 1|(link<<2));
-		mem2 = find_resource(dev, 2|(link<<2));
+		mem1 = find_resource(dev, 1|(link->link_num<<2));
+		mem2 = find_resource(dev, 2|(link->link_num<<2));
 
 		printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
 			mem1->base, mem1->limit, mem1->size, mem1->align);
@@ -939,8 +940,8 @@ static void amdfam10_domain_set_resource
 #endif
 
 	pci_tolm = 0xffffffffUL;
-	for(link = 0; link<dev->links; link++) {
-		pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
+	for(link = dev->link_list; link; link = link->next) {
+		pci_tolm = find_pci_tolm(link, pci_tolm);
 	}
 
 	// FIXME handle interleaved nodes. If you fix this here, please fix
@@ -1084,11 +1085,9 @@ static void amdfam10_domain_set_resource
 #endif
 	}
 
-	for(link = 0; link < dev->links; link++) {
-		struct bus *bus;
-		bus = &dev->link[link];
-		if (bus->children) {
-			assign_resources(bus);
+	for(link = dev->link_list; link; link = link->next) {
+		if (link->children) {
+			assign_resources(link);
 		}
 	}
 }
@@ -1097,6 +1096,7 @@ static u32 amdfam10_domain_scan_bus(devi
 {
 	u32 reg;
 	int i;
+	struct bus *link;
 	/* Unmap all of the HT chains */
 	for(reg = 0xe0; reg <= 0xec; reg += 4) {
 		f1_write_config32(reg, 0);
@@ -1114,8 +1114,8 @@ static u32 amdfam10_domain_scan_bus(devi
 #endif
 
 
-	for(i = 0; i < dev->links; i++) {
-		max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CONFIG_CDB, 0), 0xff, max);
+	for(link = dev->link_list; link; link = link->next) {
+		max = pci_scan_bus(link, PCI_DEVFN(CONFIG_CDB, 0), 0xff, max);
 	}
 
 	/* Tune the hypertransport transaction for best performance.
@@ -1129,12 +1129,12 @@ static u32 amdfam10_domain_scan_bus(devi
 			u32 httc;
 			httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
 			httc &= ~HTTC_RSP_PASS_PW;
-			if (!dev->link[0].disable_relaxed_ordering) {
+			if (!dev->link_list->disable_relaxed_ordering) {
 				httc |= HTTC_RSP_PASS_PW;
 			}
 			printk(BIOS_SPEW, "%s passpw: %s\n",
 				dev_path(dev),
-				(!dev->link[0].disable_relaxed_ordering)?
+				(!dev->link_list->disable_relaxed_ordering)?
 				"enabled":"disabled");
 			pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
 		}
@@ -1197,6 +1197,42 @@ static void sysconf_init(device_t dev) /
 #endif
 }
 
+static void add_more_links(device_t dev, unsigned total_links)
+{
+	struct bus *link, *last = NULL;
+	int link_num;
+
+	for (link = dev->link_list; link; link = link->next)
+		last = link;
+
+	if (last) {
+		int links = total_links - last->link_num;
+		link_num = last->link_num;
+		if (links > 0) {
+			link = malloc(links*sizeof(*link));
+			if (!link)
+				die("Couldn't allocate more links!\n");
+			memset(link, 0, links*sizeof(*link));
+			last->next = link;
+		}
+	}
+	else {
+		link_num = -1;
+		link = malloc(total_links*sizeof(*link));
+		memset(link, 0, total_links*sizeof(*link));
+		dev->link_list = link;
+	}
+
+	for (link_num = link_num + 1; link_num < total_links; link_num++) {
+		link->link_num = link_num;
+		link->dev = dev;
+		link->next = link + 1;
+		last = link;
+		link = link->next;
+	}
+	last->next = NULL;
+}
+
 static u32 cpu_bus_scan(device_t dev, u32 max)
 {
 	struct bus *cpu_bus;
@@ -1250,7 +1286,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 			printk(BIOS_DEBUG, "%s found\n", dev_path(dev_mc));
 			pci_domain = dev_mc->bus->dev;
 			if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
-				if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) {
+				if((pci_domain->link_list) && (pci_domain->link_list->children == dev_mc)) {
 					printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
 					dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
 					printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
@@ -1279,18 +1315,19 @@ static u32 cpu_bus_scan(device_t dev, u3
 
 #if CONFIG_CBB && (NODE_NUMS > 32)
 	if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe
-		if(pci_domain->links==1) {
-			pci_domain->links++; // from 1 to 2
-			pci_domain->link[1].link = 1;
-			pci_domain->link[1].dev = pci_domain;
-			pci_domain->link[1].children = 0;
-			printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(pci_domain), pci_domain->links);
+		if(pci_domain->link_list && !pci_domain->link_list->next) {
+			struct bus *new_link = new_link(pci_domain);
+			pci_domain->link_list->next = new_link;
+			new_link->link_num = 1;
+			new_link->dev = pci_domain;
+			new_link->children = 0;
+			printk(BIOS_DEBUG, "%s links now 2\n", dev_path(pci_domain));
 		}
-		pci_domain->link[1].secondary = CONFIG_CBB - 1;
+		pci_domain->link_list->next->secondary = CONFIG_CBB - 1;
 	}
 #endif
 	/* Find which cpus are present */
-	cpu_bus = &dev->link[0];
+	cpu_bus = dev->link_list;
 	for(i = 0; i < nodes; i++) {
 		device_t cdb_dev, cpu;
 		struct device_path cpu_path;
@@ -1304,7 +1341,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 		if(i>=32) {
 			busn--;
 			devn-=32;
-			pbus = &(pci_domain->link[1]);
+			pbus = pci_domain->link_list->next);
 		}
 #endif
 
@@ -1325,21 +1362,13 @@ static u32 cpu_bus_scan(device_t dev, u3
 			/* Ok, We need to set the links for that device.
 			 * otherwise the device under it will not be scanned
 			 */
-			int link;
 			int linknum;
 #if CONFIG_HT3_SUPPORT==1
 			linknum = 8;
 #else
 			linknum = 4;
 #endif
-			if (cdb_dev->links < linknum) {
-				for(link=cdb_dev->links; link<linknum; link++) {
-					 cdb_dev->link[link].link = link;
-					 cdb_dev->link[link].dev = cdb_dev;
-				}
-				cdb_dev->links = linknum;
-				printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(cdb_dev), cdb_dev->links);
-			}
+			add_more_links(cdb_dev, linknum);
 		}
 
 		cores_found = 0; // one core
@@ -1410,7 +1439,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/amd/amdk8/northbridge.c
===================================================================
--- svn.orig/src/northbridge/amd/amdk8/northbridge.c
+++ svn/src/northbridge/amd/amdk8/northbridge.c
@@ -81,7 +81,7 @@ static u32 amdk8_nodeid(device_t dev)
 	return (dev->path.pci.devfn >> 3) - 0x18;
 }
 
-static u32 amdk8_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink,
+static u32 amdk8_scan_chain(device_t dev, u32 nodeid, struct bus *link, u32 link_num, u32 sblink,
 				u32 max, u32 offset_unitid)
 {
 
@@ -94,15 +94,15 @@ static u32 amdk8_scan_chain(device_t dev
 		u32 min_bus;
 		u32 max_devfn;
 
-		dev->link[link].cap = 0x80 + (link *0x20);
+		link->cap = 0x80 + (link_num *0x20);
 		do {
-			link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
+			link_type = pci_read_config32(dev, link->cap + 0x18);
 		} while(link_type & ConnectionPending);
 		if (!(link_type & LinkConnected)) {
 			return max;
 		}
 		do {
-			link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
+			link_type = pci_read_config32(dev, link->cap + 0x18);
 		} while(!(link_type & InitComplete));
 		if (!(link_type & NonCoherent)) {
 			return max;
@@ -120,7 +120,7 @@ static u32 amdk8_scan_chain(device_t dev
 			}
 			if (((config & 3) == 3) &&
 				(((config >> 4) & 7) == nodeid) &&
-				(((config >> 8) & 3) == link)) {
+				(((config >> 8) & 3) == link_num)) {
 				break;
 			}
 		}
@@ -140,7 +140,7 @@ static u32 amdk8_scan_chain(device_t dev
 		 */
 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
 		// first chain will on bus 0
-		if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
+		if((nodeid == 0) && (sblink==link_num)) { // actually max is 0 here
 			min_bus = max;
 		}
 	#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
@@ -160,13 +160,13 @@ static u32 amdk8_scan_chain(device_t dev
 #endif
 		max_bus = 0xff;
 
-		dev->link[link].secondary = min_bus;
-		dev->link[link].subordinate = max_bus;
+		link->secondary = min_bus;
+		link->subordinate = max_bus;
 
 		/* Read the existing primary/secondary/subordinate bus
 		 * number configuration.
 		 */
-		busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
+		busses = pci_read_config32(dev, link->cap + 0x14);
 		config_busses = f1_read_config32(config_reg);
 
 		/* Configure the bus numbers for this bridge: the configuration
@@ -175,17 +175,17 @@ static u32 amdk8_scan_chain(device_t dev
 		 */
 		busses &= 0xff000000;
 		busses |= (((unsigned int)(dev->bus->secondary) << 0) |
-			((unsigned int)(dev->link[link].secondary) << 8) |
-			((unsigned int)(dev->link[link].subordinate) << 16));
-		pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
+			((unsigned int)(link->secondary) << 8) |
+			((unsigned int)(link->subordinate) << 16));
+		pci_write_config32(dev, link->cap + 0x14, busses);
 
 		config_busses &= 0x000fc88;
 		config_busses |=
 			(3 << 0) |  /* rw enable, no device compare */
 			(( nodeid & 7) << 4) |
-			(( link & 3 ) << 8) |
-			((dev->link[link].secondary) << 16) |
-			((dev->link[link].subordinate) << 24);
+			(( link_num & 3 ) << 8) |
+			((link->secondary) << 16) |
+			((link->subordinate) << 24);
 		f1_write_config32(config_reg, config_busses);
 
 		/* Now we can scan all of the subordinate busses i.e. the
@@ -200,18 +200,18 @@ static u32 amdk8_scan_chain(device_t dev
 		else
 			max_devfn = (0x1f<<3) | 7;
 
-		max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
+		max = hypertransport_scan_chain(link, 0, max_devfn, max, ht_unitid_base, offset_unitid);
 
 		/* We know the number of busses behind this bridge.  Set the
 		 * subordinate bus number to it's real value
 		 */
-		dev->link[link].subordinate = max;
+		link->subordinate = max;
 		busses = (busses & 0xff00ffff) |
-			((unsigned int) (dev->link[link].subordinate) << 16);
-		pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
+			((unsigned int) (link->subordinate) << 16);
+		pci_write_config32(dev, link->cap + 0x14, busses);
 
 		config_busses = (config_busses & 0x00ffffff) |
-			(dev->link[link].subordinate << 24);
+			(link->subordinate << 24);
 		f1_write_config32(config_reg, config_busses);
 
 		{
@@ -232,7 +232,7 @@ static u32 amdk8_scan_chain(device_t dev
 static unsigned amdk8_scan_chains(device_t dev, unsigned max)
 {
 	unsigned nodeid;
-	unsigned link;
+	struct bus *link;
 	unsigned sblink = 0;
 	unsigned offset_unitid = 0;
 
@@ -244,23 +244,25 @@ static unsigned amdk8_scan_chains(device
 	#if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 		offset_unitid = 1;
 	#endif
-		max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
+		for (link = dev->link_list; link; link = link->next)
+			if (link->link_num == sblink)
+				max = amdk8_scan_chain(dev, nodeid, link, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
 #endif
 	}
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
-		if( (nodeid == 0) && (sblink == link) ) continue; //already done
+		if( (nodeid == 0) && (sblink == link->link_num) ) continue; //already done
 #endif
 		offset_unitid = 0;
 		#if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 			#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
-			if((nodeid == 0) && (sblink == link))
+			if((nodeid == 0) && (sblink == link->link_num))
 			#endif
 				offset_unitid = 1;
 		#endif
 
-		max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
+		max = amdk8_scan_chain(dev, nodeid, link, link->link_num, sblink, max, offset_unitid);
 	}
 	return max;
 }
@@ -375,21 +377,22 @@ static void amdk8_create_vga_resource(de
 
 static void amdk8_read_resources(device_t dev)
 {
-	unsigned nodeid, link;
+	unsigned nodeid;
+	struct bus *link;
 	nodeid = amdk8_nodeid(dev);
-	for(link = 0; link < dev->links; link++) {
-		if (dev->link[link].children) {
-			amdk8_link_read_bases(dev, nodeid, link);
+	for(link = dev->link_list; link; link = link->next) {
+		if (link->children) {
+			amdk8_link_read_bases(dev, nodeid, link->link_num);
 		}
 	}
-
 	amdk8_create_vga_resource(dev, nodeid);
 }
 
 static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
 {
+	struct bus *link;
 	resource_t rbase, rend;
-	unsigned reg, link;
+	unsigned reg, link_num;
 	char buf[50];
 
 	/* Make certain the resource has actually been set */
@@ -426,7 +429,17 @@ static void amdk8_set_resource(device_t 
 
 	/* Get the register and link */
 	reg  = resource->index & 0xfc;
-	link = IOINDEX_LINK(resource->index);
+	link_num = IOINDEX_LINK(resource->index);
+
+	for (link = dev->link_list; link; link = link->next)
+		if (link->link_num == link_num)
+			break;
+
+	if (link == NULL) {
+		printk(BIOS_ERR, "%s: can't find link %x for %lx\n", __func__,
+			   link_num, resource->index);
+		return;
+	}
 
 	if (resource->flags & IORESOURCE_IO) {
 		u32 base, limit;
@@ -437,15 +450,15 @@ static void amdk8_set_resource(device_t 
 		base  |= 3;
 		limit &= 0xfe000fc8;
 		limit |= rend & 0x01fff000;
-		limit |= (link & 3) << 4;
+		limit |= (link_num & 3) << 4;
 		limit |= (nodeid & 7);
 
-		if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
+		if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 			printk(BIOS_SPEW, "%s, enabling legacy VGA IO forwarding for %s link 0x%x\n",
-				    __func__, dev_path(dev), link);
+				    __func__, dev_path(dev), link_num);
 			base |= PCI_IO_BASE_VGA_EN;
 		}
-		if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
+		if (link->bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
 			base |= PCI_IO_BASE_NO_ISA;
 		}
 
@@ -461,14 +474,14 @@ static void amdk8_set_resource(device_t 
 		base  |= 3;
 		limit &= 0x00000048;
 		limit |= (rend >> 8) & 0xffffff00;
-		limit |= (link & 3) << 4;
+		limit |= (link_num & 3) << 4;
 		limit |= (nodeid & 7);
 		f1_write_config32(reg + 0x4, limit);
 		f1_write_config32(reg, base);
 	}
 	resource->flags |= IORESOURCE_STORED;
 	sprintf(buf, " <node %x link %x>",
-		nodeid, link);
+		nodeid, link_num);
 	report_resource_stored(dev, resource, buf);
 }
 
@@ -479,18 +492,18 @@ extern device_t vga_pri;	// the primary 
 static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
 {
 	struct resource *resource;
-	unsigned link;
+	struct bus *link;
 
 	/* find out which link the VGA card is connected,
 	 * we only deal with the 'first' vga card */
-	for (link = 0; link < dev->links; link++) {
-		if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
+	for (link = dev->link_list; link; link = link->next) {
+		if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 #if CONFIG_CONSOLE_VGA_MULTI == 1
-			printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
-				dev->link[link].secondary,dev->link[link].subordinate);
+			printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d link bus range [%d,%d]\n", vga_pri->bus->secondary,
+				link->secondary,link->subordinate);
 			/* We need to make sure the vga_pri is under the link */
-			if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
-				(vga_pri->bus->secondary <= dev->link[link].subordinate )
+			if((vga_pri->bus->secondary >= link->secondary ) &&
+				(vga_pri->bus->secondary <= link->subordinate )
 			)
 #endif
 			break;
@@ -498,13 +511,13 @@ static void amdk8_create_vga_resource(de
 	}
 
 	/* no VGA card installed */
-	if (link == dev->links)
+	if (link == NULL)
 		return;
 
-	printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
+	printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link->link_num);
 
 	/* allocate a temp resource for the legacy VGA buffer */
-	resource = new_resource(dev, IOINDEX(4, link));
+	resource = new_resource(dev, IOINDEX(4, link->link_num));
 	if(!resource){
 		printk(BIOS_DEBUG, "VGA: %s out of resources.\n", dev_path(dev));
 		return;
@@ -518,7 +531,8 @@ static void amdk8_create_vga_resource(de
 
 static void amdk8_set_resources(device_t dev)
 {
-	unsigned nodeid, link;
+	unsigned nodeid;
+	struct bus *bus;
 	struct resource *res;
 
 	/* Find the nodeid */
@@ -553,9 +567,7 @@ static void amdk8_set_resources(device_t
 
 	compact_resources(dev);
 
-	for(link = 0; link < dev->links; link++) {
-		struct bus *bus;
-		bus = &dev->link[link];
+	for(bus = dev->link_list; bus; bus = bus->next) {
 		if (bus->children) {
 			assign_resources(bus);
 		}
@@ -909,7 +921,7 @@ static void amdk8_domain_set_resources(d
 	}
 #endif
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 
 	// FIXME handle interleaved nodes. If you fix this here, please fix
 	// amdfam10, too.
@@ -1066,7 +1078,7 @@ static void amdk8_domain_set_resources(d
 		}
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 
 }
 
@@ -1078,7 +1090,7 @@ static u32 amdk8_domain_scan_bus(device_
 	for(reg = 0xe0; reg <= 0xec; reg += 4) {
 		f1_write_config32(reg, 0);
 	}
-	max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
+	max = pci_scan_bus(dev->link_list, PCI_DEVFN(0x18, 0), 0xff, max);
 
 	/* Tune the hypertransport transaction for best performance.
 	 * Including enabling relaxed ordering if it is safe.
@@ -1091,12 +1103,12 @@ static u32 amdk8_domain_scan_bus(device_
 			u32 httc;
 			httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
 			httc &= ~HTTC_RSP_PASS_PW;
-			if (!dev->link[0].disable_relaxed_ordering) {
+			if (!dev->link_list->disable_relaxed_ordering) {
 				httc |= HTTC_RSP_PASS_PW;
 			}
 			printk(BIOS_SPEW, "%s passpw: %s\n",
 				dev_path(dev),
-				(!dev->link[0].disable_relaxed_ordering)?
+				(!dev->link_list->disable_relaxed_ordering)?
 				"enabled":"disabled");
 			pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
 		}
@@ -1113,6 +1125,42 @@ static struct device_operations pci_doma
 	.ops_pci_bus	  = &pci_cf8_conf1,
 };
 
+static void add_more_links(device_t dev, unsigned total_links)
+{
+	struct bus *link, *last = NULL;
+	int link_num;
+
+	for (link = dev->link_list; link; link = link->next)
+		last = link;
+
+	if (last) {
+		int links = total_links - last->link_num;
+		link_num = last->link_num;
+		if (links > 0) {
+			link = malloc(links*sizeof(*link));
+			if (!link)
+				die("Couldn't allocate more links!\n");
+			memset(link, 0, links*sizeof(*link));
+			last->next = link;
+		}
+	}
+	else {
+		link_num = -1;
+		link = malloc(total_links*sizeof(*link));
+		memset(link, 0, total_links*sizeof(*link));
+		dev->link_list = link;
+	}
+
+	for (link_num = link_num + 1; link_num < total_links; link_num++) {
+		link->link_num = link_num;
+		link->dev = dev;
+		link->next = link + 1;
+		last = link;
+		link = link->next;
+	}
+	last->next = NULL;
+}
+
 static u32 cpu_bus_scan(device_t dev, u32 max)
 {
 	struct bus *cpu_bus;
@@ -1165,7 +1213,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 	}
 
 	/* Find which cpus are present */
-	cpu_bus = &dev->link[0];
+	cpu_bus = dev->link_list;
 	for(i = 0; i < sysconf.nodes; i++) {
 		device_t cpu_dev, cpu;
 		struct device_path cpu_path;
@@ -1187,11 +1235,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 			 */
 			dev_f0 = dev_find_slot(0, PCI_DEVFN(0x18+i,0));
 			if(dev_f0) {
-				dev_f0->links = 3;
-				for(local_j=0;local_j<3;local_j++) {
-					dev_f0->link[local_j].link = local_j;
-					dev_f0->link[local_j].dev = dev_f0;
-				}
+				add_more_links(dev_f0, 3);
 			}
 		}
 
@@ -1290,7 +1334,7 @@ static u32 cpu_bus_scan(device_t dev, u3
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/amd/gx1/northbridge.c
===================================================================
--- svn.orig/src/northbridge/amd/gx1/northbridge.c
+++ svn/src/northbridge/amd/gx1/northbridge.c
@@ -115,8 +115,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
         uint32_t pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned int tomk, tolmk;
 		unsigned int ramreg = 0;
@@ -163,7 +163,7 @@ static void pci_domain_set_resources(dev
 		idx = 10;
 		ram_resource(dev, idx++, 0, tolmk);
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -177,7 +177,7 @@ static struct device_operations pci_doma
 static void cpu_bus_init(device_t dev)
 {
 	printk(BIOS_SPEW, "%s:%s()\n", NORTHBRIDGE_FILE, __func__);
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/amd/gx2/northbridge.c
===================================================================
--- svn.orig/src/northbridge/amd/gx2/northbridge.c
+++ svn/src/northbridge/amd/gx2/northbridge.c
@@ -303,11 +303,9 @@ static void set_resources(struct device 
                 pci_set_resource(dev, resource);
         }
 #endif
-        unsigned link;
+	struct bus *bus;
 
-        for(link = 0; link < dev->links; link++) {
-                struct bus *bus;
-                bus = &dev->link[link];
+	for(bus = dev->link_list; bus; bus = bus->next) {
                 if (bus->children) {
                         assign_resources(bus);
                 }
@@ -402,8 +400,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
         u32 pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned int tomk, tolmk;
 		unsigned int ramreg = 0;
@@ -444,7 +442,7 @@ static void pci_domain_set_resources(dev
 		ram_resource(dev, idx++, 0, tolmk);
 	}
 #endif
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -457,7 +455,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/amd/lx/northbridge.c
===================================================================
--- svn.orig/src/northbridge/amd/lx/northbridge.c
+++ svn/src/northbridge/amd/lx/northbridge.c
@@ -318,7 +318,6 @@ static void northbridge_init(device_t de
 
 static void northbridge_set_resources(struct device *dev)
 {
-	unsigned link;
 	uint8_t line;
 
 #if 0
@@ -331,9 +330,8 @@ static void northbridge_set_resources(st
 	}
 #endif
 
-	for (link = 0; link < dev->links; link++) {
-		struct bus *bus;
-		bus = &dev->link[link];
+	struct bus *bus;
+	for (bus = dev->link_list; bus; bus = bus->next) {
 		if (bus->children) {
 			printk(BIOS_DEBUG, "my_dev_set_resources: assign_resources %d\n",
 			     bus->secondary);
@@ -402,7 +400,7 @@ static void pci_domain_set_resources(dev
 
 	printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __func__);
 
-	mc_dev = dev->link[0].children;
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		tomk = get_systop() / 1024;
 		/* Report the memory regions
@@ -418,7 +416,7 @@ static void pci_domain_set_resources(dev
 #endif
 	}
 
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static void pci_domain_enable(device_t dev)
@@ -452,7 +450,7 @@ static void cpu_bus_init(device_t dev)
 {
 	printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __func__);
 
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/e7501/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/e7501/northbridge.c
+++ svn/src/northbridge/intel/e7501/northbridge.c
@@ -58,8 +58,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
         uint32_t pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		/* Figure out which areas are/should be occupied by RAM.
 		 * This is all computed in kilobytes and converted to/from
@@ -135,7 +135,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -149,7 +149,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/e7520/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/e7520/northbridge.c
+++ svn/src/northbridge/intel/e7520/northbridge.c
@@ -62,7 +62,7 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
 	uint32_t pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
+        pci_tolm = find_pci_tolm(dev->link_list);
 
 #if 1
 	printk(BIOS_DEBUG, "PCI mem marker = %x\n", pci_tolm);
@@ -72,7 +72,7 @@ static void pci_domain_set_resources(dev
 		pci_tolm = 0xe0000000;
 	/* Ensure pci_tolm is 128M aligned */
 	pci_tolm &= 0xf8000000;
-	mc_dev = dev->link[0].children;
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		/* Figure out which areas are/should be occupied by RAM.
 		 * This is all computed in kilobytes and converted to/from
@@ -151,7 +151,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static u32 e7520_domain_scan_bus(device_t dev, u32 max)
@@ -219,7 +219,7 @@ static const struct pci_driver mc_driver
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/e7525/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/e7525/northbridge.c
+++ svn/src/northbridge/intel/e7525/northbridge.c
@@ -62,7 +62,7 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
 	uint32_t pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
+        pci_tolm = find_pci_tolm(dev->link_list);
 
 #if 1
 	printk(BIOS_DEBUG, "PCI mem marker = %x\n", pci_tolm);
@@ -72,7 +72,7 @@ static void pci_domain_set_resources(dev
 		pci_tolm = 0xe0000000;
 	/* Ensure pci_tolm is 128M aligned */
 	pci_tolm &= 0xf8000000;
-	mc_dev = dev->link[0].children;
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		/* Figure out which areas are/should be occupied by RAM.
 		 * This is all computed in kilobytes and converted to/from
@@ -151,7 +151,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static u32 e7525_domain_scan_bus(device_t dev, u32 max)
@@ -219,7 +219,7 @@ static const struct pci_driver mc_driver
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i3100/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i3100/northbridge.c
+++ svn/src/northbridge/intel/i3100/northbridge.c
@@ -83,7 +83,7 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
 	u32 pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
+        pci_tolm = find_pci_tolm(dev->link_list);
 
 #if 1
 	printk(BIOS_DEBUG, "PCI mem marker = %x\n", pci_tolm);
@@ -93,7 +93,7 @@ static void pci_domain_set_resources(dev
 		pci_tolm = 0xe0000000;
 	/* Ensure pci_tolm is 128M aligned */
 	pci_tolm &= 0xf8000000;
-	mc_dev = dev->link[0].children;
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		/* Figure out which areas are/should be occupied by RAM.
 		 * This is all computed in kilobytes and converted to/from
@@ -172,7 +172,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static u32 i3100_domain_scan_bus(device_t dev, u32 max)
@@ -240,7 +240,7 @@ static const struct pci_driver mc_driver
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i3100/pciexp_porta_ep80579.c
===================================================================
--- svn.orig/src/northbridge/intel/i3100/pciexp_porta_ep80579.c
+++ svn/src/northbridge/intel/i3100/pciexp_porta_ep80579.c
@@ -56,7 +56,7 @@ static void pcie_init(struct device *dev
 
 static void pcie_bus_enable_resources(struct device *dev)
 {
-	if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
+	if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 		printk(BIOS_SPEW, "Enable VGA IO/MEM forwarding on PCIe port\n");
 		pci_write_config8(dev, PCI_BRIDGE_CONTROL, 8);
 
Index: svn/src/northbridge/intel/i440bx/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i440bx/northbridge.c
+++ svn/src/northbridge/intel/i440bx/northbridge.c
@@ -82,8 +82,8 @@ static void i440bx_domain_set_resources(
 	device_t mc_dev;
 	uint32_t pci_tolm;
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+	pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned long tomk, tolmk;
 		int idx;
@@ -118,7 +118,7 @@ static void i440bx_domain_set_resources(
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -131,7 +131,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i440lx/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i440lx/northbridge.c
+++ svn/src/northbridge/intel/i440lx/northbridge.c
@@ -110,8 +110,8 @@ static void i440lx_domain_set_resources(
 	device_t mc_dev;
 	uint32_t pci_tolm;
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+	pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned long tomk, tolmk;
 		int idx;
@@ -146,7 +146,7 @@ static void i440lx_domain_set_resources(
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -159,7 +159,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i82810/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i82810/northbridge.c
+++ svn/src/northbridge/intel/i82810/northbridge.c
@@ -119,8 +119,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
 	uint32_t pci_tolm;
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+	pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 
 	if (mc_dev) {
 		/* Figure out which areas are/should be occupied by RAM.
@@ -178,7 +178,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -191,7 +191,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i82830/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i82830/northbridge.c
+++ svn/src/northbridge/intel/i82830/northbridge.c
@@ -111,8 +111,8 @@ static void pci_domain_set_resources(dev
 	uint32_t pci_tolm;
 	int igd_memory = 0;
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+	pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (!mc_dev)
 		return;
 
@@ -152,7 +152,7 @@ static void pci_domain_set_resources(dev
 	ram_resource(dev, idx++, 768, 256);
 	ram_resource(dev, idx++, 1024, tolmk - 1024);
 
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 
 #if CONFIG_WRITE_HIGH_TABLES==1
 	/* Leave some space for ACPI, PIRQ and MP tables */
@@ -171,7 +171,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i855/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i855/northbridge.c
+++ svn/src/northbridge/intel/i855/northbridge.c
@@ -83,8 +83,8 @@ static void pci_domain_set_resources(dev
         printk(BIOS_DEBUG, "Entered with dev vid = %x\n", dev->vendor);
 	printk(BIOS_DEBUG, "Entered with dev did = %x\n", dev->device);
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children->sibling;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children->sibling;
 	printk(BIOS_DEBUG, "MC dev vendor = %x\n", mc_dev->vendor);
 	printk(BIOS_DEBUG, "MC dev device = %x\n", mc_dev->device);
 
@@ -134,7 +134,7 @@ static void pci_domain_set_resources(dev
 		high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -147,7 +147,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/intel/i945/northbridge.c
===================================================================
--- svn.orig/src/northbridge/intel/i945/northbridge.c
+++ svn/src/northbridge/intel/i945/northbridge.c
@@ -138,7 +138,7 @@ static void pci_domain_set_resources(dev
 	/* Can we find out how much memory we can use at most
 	 * this way?
 	 */
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 	printk(BIOS_DEBUG, "pci_tolm: 0x%x\n", pci_tolm);
 
 	printk(BIOS_SPEW, "Base of stolen memory: 0x%08x\n",
@@ -208,7 +208,7 @@ static void pci_domain_set_resources(dev
 		ram_resource(dev, 5, 4096 * 1024, tomk - 4 * 1024 * 1024);
 	}
 
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 
 #if CONFIG_WRITE_HIGH_TABLES==1
 	/* Leave some space for ACPI, PIRQ and MP tables */
@@ -326,7 +326,7 @@ static const struct pci_driver mc_driver
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/cn400/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/cn400/northbridge.c
+++ svn/src/northbridge/via/cn400/northbridge.c
@@ -233,7 +233,7 @@ static void cn400_domain_set_resources(d
 
 	printk(BIOS_SPEW, "Entering %s.\n", __func__);
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 	mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
 				 PCI_DEVICE_ID_VIA_CN400_MEMCTRL, 0);
 
@@ -267,7 +267,7 @@ static void cn400_domain_set_resources(d
 		ram_resource(dev, idx++, 768,
 			     (tolmk - 768 - CONFIG_VIDEO_MB * 1024));
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 
 	printk(BIOS_SPEW, "Leaving %s.\n", __func__);
 }
@@ -276,7 +276,7 @@ static unsigned int cn400_domain_scan_bu
 {
 	printk(BIOS_DEBUG, "Entering %s.\n", __func__);
 
-	max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+	max = pci_scan_bus(dev->link_list, PCI_DEVFN(0, 0), 0xff, max);
 	return max;
 }
 
@@ -290,7 +290,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/cn700/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/cn700/northbridge.c
+++ svn/src/northbridge/via/cn700/northbridge.c
@@ -157,7 +157,7 @@ static void pci_domain_set_resources(dev
 
 	printk(BIOS_SPEW, "Entering cn700 pci_domain_set_resources.\n");
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 	mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
 				 PCI_DEVICE_ID_VIA_CN700_MEMCTRL, 0);
 
@@ -199,7 +199,7 @@ static void pci_domain_set_resources(dev
 		ram_resource(dev, idx++, 768,
 			     (tolmk - 768 - CONFIG_VIDEO_MB * 1024));
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -212,7 +212,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/cx700/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/cx700/northbridge.c
+++ svn/src/northbridge/via/cx700/northbridge.c
@@ -87,7 +87,7 @@ static void pci_domain_set_resources(dev
 	unsigned char rambits;
 	int idx;
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 	mc_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3324, 0);
 
 	rambits = pci_read_config8(mc_dev, 0x88);
@@ -128,7 +128,7 @@ static void pci_domain_set_resources(dev
 	/* TODO: Hole needed? Should this go elsewhere? */
 	ram_resource(dev, idx++, 0, 640);	/* first 640k */
 	ram_resource(dev, idx++, 768, (tolmk - 768));	/* leave a hole for vga */
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -141,7 +141,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/vt8601/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/vt8601/northbridge.c
+++ svn/src/northbridge/via/vt8601/northbridge.c
@@ -98,8 +98,8 @@ static void pci_domain_set_resources(dev
 	device_t mc_dev;
         uint32_t pci_tolm;
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned long tomk, tolmk;
 		unsigned char rambits;
@@ -140,7 +140,7 @@ static void pci_domain_set_resources(dev
 		idx = 10;
 		ram_resource(dev, idx++, 0, tolmk);
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -153,7 +153,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/vt8623/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/vt8623/northbridge.c
+++ svn/src/northbridge/via/vt8623/northbridge.c
@@ -158,8 +158,8 @@ static void pci_domain_set_resources(dev
 
 	printk(BIOS_SPEW, "Entering vt8623 pci_domain_set_resources.\n");
 
-        pci_tolm = find_pci_tolm(&dev->link[0]);
-	mc_dev = dev->link[0].children;
+        pci_tolm = find_pci_tolm(dev->link_list);
+	mc_dev = dev->link_list->children;
 	if (mc_dev) {
 		unsigned long tomk, tolmk;
 		unsigned char rambits;
@@ -201,7 +201,7 @@ static void pci_domain_set_resources(dev
 		ram_resource(dev, idx++, 0, 640);		/* first 640k */
 		ram_resource(dev, idx++, 768, tolmk - 768);	/* leave a hole for vga */
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -214,7 +214,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-        initialize_cpus(&dev->link[0]);
+        initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/northbridge/via/vx800/northbridge.c
===================================================================
--- svn.orig/src/northbridge/via/vx800/northbridge.c
+++ svn/src/northbridge/via/vx800/northbridge.c
@@ -128,7 +128,7 @@ static void pci_domain_set_resources(dev
 
 	printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n");
 
-	pci_tolm = find_pci_tolm(&dev->link[0]);
+	pci_tolm = find_pci_tolm(dev->link_list);
 	mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
 				 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
 
@@ -175,7 +175,7 @@ if register with invalid value we set fr
 		/* Leave a hole for vga, 0xa0000 - 0xc0000 */
 		ram_resource(dev, idx++, 768, (tolmk - 768));
 	}
-	assign_resources(&dev->link[0]);
+	assign_resources(dev->link_list);
 }
 
 static struct device_operations pci_domain_ops = {
@@ -188,7 +188,7 @@ static struct device_operations pci_doma
 
 static void cpu_bus_init(device_t dev)
 {
-	initialize_cpus(&dev->link[0]);
+	initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_noop(device_t dev)
Index: svn/src/southbridge/amd/amd8131/amd8131_bridge.c
===================================================================
--- svn.orig/src/southbridge/amd/amd8131/amd8131_bridge.c
+++ svn/src/southbridge/amd/amd8131/amd8131_bridge.c
@@ -25,7 +25,7 @@ static void amd8131_walk_children(struct
 			continue;
 		}
 		if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			amd8131_walk_children(&child->link[0], visit, ptr);
+			amd8131_walk_children(child->link_list, visit, ptr);
 		}
 		visit(child, ptr);
 	}
Index: svn/src/southbridge/amd/amd8132/amd8132_bridge.c
===================================================================
--- svn.orig/src/southbridge/amd/amd8132/amd8132_bridge.c
+++ svn/src/southbridge/amd/amd8132/amd8132_bridge.c
@@ -47,7 +47,7 @@ static void amd8132_walk_children(struct
 			continue;
 		}
 		if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			amd8132_walk_children(&child->link[0], visit, ptr);
+			amd8132_walk_children(child->link_list, visit, ptr);
 		}
 		visit(child, ptr);
 	}
Index: svn/src/southbridge/amd/sb600/sb600_lpc.c
===================================================================
--- svn.orig/src/southbridge/amd/sb600/sb600_lpc.c
+++ svn/src/southbridge/amd/sb600/sb600_lpc.c
@@ -106,7 +106,7 @@ static void sb600_lpc_read_resources(dev
  */
 static void sb600_lpc_enable_childrens_resources(device_t dev)
 {
-	u32 link;
+	struct bus *link;
 	u32 reg, reg_x;
 	int var_num = 0;
 	u16 reg_var[3];
@@ -114,9 +114,9 @@ static void sb600_lpc_enable_childrens_r
 	reg = pci_read_config32(dev, 0x44);
 	reg_x = pci_read_config32(dev, 0x48);
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for (child = dev->link[link].children; child;
+		for (child = link->children; child;
 		     child = child->sibling) {
 			enable_resources(child);
 			if (child->enabled
Index: svn/src/southbridge/amd/sb700/sb700_lpc.c
===================================================================
--- svn.orig/src/southbridge/amd/sb700/sb700_lpc.c
+++ svn/src/southbridge/amd/sb700/sb700_lpc.c
@@ -118,7 +118,7 @@ static void sb700_lpc_set_resources(stru
  */
 static void sb700_lpc_enable_childrens_resources(device_t dev)
 {
-	u32 link;
+	struct bus *link;
 	u32 reg, reg_x;
 	int var_num = 0;
 	u16 reg_var[3];
@@ -126,9 +126,9 @@ static void sb700_lpc_enable_childrens_r
 	reg = pci_read_config32(dev, 0x44);
 	reg_x = pci_read_config32(dev, 0x48);
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for (child = dev->link[link].children; child;
+		for (child = link->children; child;
 		     child = child->sibling) {
 			enable_resources(child);
 			if (child->enabled
Index: svn/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
===================================================================
--- svn.orig/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
+++ svn/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
@@ -67,14 +67,14 @@ static void bcm5785_lpc_read_resources(d
  */
 static void bcm5785_lpc_enable_childrens_resources(device_t dev)
 {
-        unsigned link;
+	struct bus *link;
 	uint32_t reg;
 
 	reg = pci_read_config8(dev, 0x44);
 
-        for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
                 device_t child;
-                for (child = dev->link[link].children; child; child = child->sibling) {
+                for (child = link->children; child; child = child->sibling) {
                         enable_resources(child);
 			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				struct resource *res;
Index: svn/src/southbridge/intel/i82801gx/i82801gx_pci.c
===================================================================
--- svn.orig/src/southbridge/intel/i82801gx/i82801gx_pci.c
+++ svn/src/southbridge/intel/i82801gx/i82801gx_pci.c
@@ -100,10 +100,10 @@ static void ich_pci_bus_enable_resources
 	/* enable IO in command register if there is VGA card
 	 * connected with (even it does not claim IO resource)
 	 */
-	if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
+	if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
 		dev->command |= PCI_COMMAND_IO;
 	ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
-	ctrl |= dev->link[0].bridge_ctrl;
+	ctrl |= dev->link_list->bridge_ctrl;
 	ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
 	printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
 	pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
Index: svn/src/southbridge/intel/pxhd/pxhd_bridge.c
===================================================================
--- svn.orig/src/southbridge/intel/pxhd/pxhd_bridge.c
+++ svn/src/southbridge/intel/pxhd/pxhd_bridge.c
@@ -41,8 +41,7 @@ static unsigned int pxhd_scan_bridge(dev
 {
 	int bus_100Mhz = 0;
 
-	dev->link[0].dev = dev;
-	dev->links = 1;
+	dev->link_list->dev = dev;
 
 	get_option(&bus_100Mhz, "pxhd_bus_speed_100");
 	if(bus_100Mhz) {
@@ -58,7 +57,7 @@ static unsigned int pxhd_scan_bridge(dev
 		pci_write_config16(dev, 0x40, word);
 
 		/* reset the bus to make the new frequencies effective */
-		pci_bus_reset(&dev->link[0]);
+		pci_bus_reset(dev->link_list);
 	}
 	return pcix_scan_bridge(dev, max);
 }
Index: svn/src/southbridge/nvidia/ck804/ck804_lpc.c
===================================================================
--- svn.orig/src/southbridge/nvidia/ck804/ck804_lpc.c
+++ svn/src/southbridge/nvidia/ck804/ck804_lpc.c
@@ -231,15 +231,15 @@ static void ck804_lpc_read_resources(dev
  */
 static void ck804_lpc_enable_childrens_resources(device_t dev)
 {
-	unsigned link;
+	struct bus *link;
 	uint32_t reg, reg_var[4];
 	int i, var_num = 0;
 
 	reg = pci_read_config32(dev, 0xa0);
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for (child = dev->link[link].children; child; child = child->sibling) {
+		for (child = link->children; child; child = child->sibling) {
 			enable_resources(child);
 			if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				struct resource *res;
Index: svn/src/southbridge/nvidia/ck804/ck804_smbus.c
===================================================================
--- svn.orig/src/southbridge/nvidia/ck804/ck804_smbus.c
+++ svn/src/southbridge/nvidia/ck804/ck804_smbus.c
@@ -23,7 +23,7 @@ static int lsmbus_recv_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_recv_byte(res->base, device);
 }
@@ -37,7 +37,7 @@ static int lsmbus_send_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_send_byte(res->base, device, val);
 }
@@ -51,7 +51,7 @@ static int lsmbus_read_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_read_byte(res->base, device, address);
 }
@@ -65,7 +65,7 @@ static int lsmbus_write_byte(device_t de
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_write_byte(res->base, device, address, val);
 }
Index: svn/src/southbridge/nvidia/mcp55/mcp55_lpc.c
===================================================================
--- svn.orig/src/southbridge/nvidia/mcp55/mcp55_lpc.c
+++ svn/src/southbridge/nvidia/mcp55/mcp55_lpc.c
@@ -205,16 +205,16 @@ static void mcp55_lpc_read_resources(dev
  */
 static void mcp55_lpc_enable_childrens_resources(device_t dev)
 {
-	unsigned link;
 	uint32_t reg, reg_var[4];
 	int i;
 	int var_num = 0;
+	struct bus *link;
 
 	reg = pci_read_config32(dev, 0xa0);
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for (child = dev->link[link].children; child; child = child->sibling) {
+		for (child = link->children; child; child = child->sibling) {
 			enable_resources(child);
 			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				struct resource *res;
Index: svn/src/southbridge/nvidia/mcp55/mcp55_smbus.c
===================================================================
--- svn.orig/src/southbridge/nvidia/mcp55/mcp55_smbus.c
+++ svn/src/southbridge/nvidia/mcp55/mcp55_smbus.c
@@ -41,7 +41,7 @@ static int lsmbus_recv_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_recv_byte(res->base, device);
 }
@@ -55,7 +55,7 @@ static int lsmbus_send_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_send_byte(res->base, device, val);
 }
@@ -69,7 +69,7 @@ static int lsmbus_read_byte(device_t dev
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_read_byte(res->base, device, address);
 }
@@ -83,7 +83,7 @@ static int lsmbus_write_byte(device_t de
 	device = dev->path.i2c.device;
 	pbus = get_pbus_smbus(dev);
 
-	res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+	res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
 
 	return do_smbus_write_byte(res->base, device, address, val);
 }
Index: svn/src/southbridge/sis/sis966/sis966_lpc.c
===================================================================
--- svn.orig/src/southbridge/sis/sis966/sis966_lpc.c
+++ svn/src/southbridge/sis/sis966/sis966_lpc.c
@@ -198,16 +198,16 @@ static void sis966_lpc_read_resources(de
  */
 static void sis966_lpc_enable_childrens_resources(device_t dev)
 {
-	unsigned link;
+	struct bus *link;
 	uint32_t reg, reg_var[4];
 	int i;
 	int var_num = 0;
 
 	reg = pci_read_config32(dev, 0xa0);
 
-	for (link = 0; link < dev->links; link++) {
+	for (link = dev->link_list; link; link = link->next) {
 		device_t child;
-		for (child = dev->link[link].children; child; child = child->sibling) {
+		for (child = link->children; child; child = child->sibling) {
 			enable_resources(child);
 			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				struct resource *res;
Index: svn/util/sconfig/main.c
===================================================================
--- svn.orig/util/sconfig/main.c
+++ svn/util/sconfig/main.c
@@ -278,10 +278,14 @@ void add_register(struct device *dev, ch
 }
 
 static void pass0(FILE *fil, struct device *ptr) {
+	if (ptr->type == device && ptr->id == 0)
+		fprintf(fil, "struct bus %s_links[];\n", ptr->name);
 	if ((ptr->type == device) && (ptr->id != 0) && (!ptr->used)) {
 		fprintf(fil, "struct device %s;\n", ptr->name);
 		if (ptr->rescnt > 0)
 			fprintf(fil, "struct resource %s_res[];\n", ptr->name);
+		if (ptr->children || ptr->multidev)
+			fprintf(fil, "struct bus %s_links[];\n", ptr->name);
 	}
 	if ((ptr->type == device) && (ptr->id != 0) && ptr->used)
 		fprintf(fil, "struct device %s;\n", ptr->aliased_name);
@@ -291,7 +295,7 @@ static void pass1(FILE *fil, struct devi
 	if (!ptr->used && (ptr->type == device)) {
 		fprintf(fil, "struct device %s = {\n", ptr->name);
 		fprintf(fil, "\t.ops = %s,\n", (ptr->ops)?(ptr->ops):"0");
-		fprintf(fil, "\t.bus = &%s.link[%d],\n", ptr->bus->name, ptr->bus->link);
+		fprintf(fil, "\t.bus = &%s_links[%d],\n", ptr->bus->name, ptr->bus->link);
 		fprintf(fil, "\t.path = {");
 		fprintf(fil, ptr->path, ptr->path_a, ptr->path_b);
 		fprintf(fil, "},\n");
@@ -301,33 +305,10 @@ static void pass1(FILE *fil, struct devi
 			fprintf(fil, "\t.resource_list = &%s_res[0],\n", ptr->name);
 		}
 		int link = 0;
-		fprintf(fil, "\t.link = {\n");
-		if (ptr->multidev) {
-			struct device *d = ptr;
-			while (d) {
-				if (device_match(d, ptr)) {
-					fprintf(fil, "\t\t[%d] = {\n", d->link);
-					fprintf(fil, "\t\t\t.link = %d,\n", d->link);
-					fprintf(fil, "\t\t\t.dev = &%s,\n", d->name);
-					if (d->children)
-						fprintf(fil, "\t\t\t.children = &%s,\n", d->children->name);
-					fprintf(fil, "\t\t},\n");
-					link++;
-				}
-				d = d->next_sibling;
-			}
-		} else {
-			if (ptr->children) {
-				fprintf(fil, "\t\t[0] = {\n");
-				fprintf(fil, "\t\t\t.link = 0,\n");
-				fprintf(fil, "\t\t\t.dev = &%s,\n", ptr->name);
-				fprintf(fil, "\t\t\t.children = &%s,\n", ptr->children->name);
-				fprintf(fil, "\t\t},\n");
-				link++;
-			}
-		}
-		fprintf(fil, "\t},\n");
-		fprintf(fil, "\t.links = %d,\n", link);
+		if (ptr->children || ptr->multidev)
+			fprintf(fil, "\t.link_list = &%s_links[0],\n", ptr->name);
+		else
+			fprintf(fil, "\t.link_list = NULL,\n", ptr->name);
 		if (ptr->sibling)
 			fprintf(fil, "\t.sibling = &%s,\n", ptr->sibling->name);
 		if (ptr->chip->chiph_exists) {
@@ -356,6 +337,37 @@ static void pass1(FILE *fil, struct devi
 		}
 		fprintf(fil, "\t };\n");
 	}
+	if (!ptr->used && ptr->type == device && (ptr->children || ptr->multidev)) {
+		fprintf(fil, "struct bus %s_links[] = {\n", ptr->name);
+		if (ptr->multidev) {
+			struct device *d = ptr;
+			while (d) {
+				if (device_match(d, ptr)) {
+					fprintf(fil, "\t\t[%d] = {\n", d->link);
+					fprintf(fil, "\t\t\t.link_num = %d,\n", d->link);
+					fprintf(fil, "\t\t\t.dev = &%s,\n", d->name);
+					if (d->children)
+						fprintf(fil, "\t\t\t.children = &%s,\n", d->children->name);
+					if (device_match(d->next_sibling, ptr))
+						fprintf(fil, "\t\t\t.next=&%s_links[%d],\n", d->name, d->link+1);
+					else
+						fprintf(fil, "\t\t\t.next = NULL,\n");
+					fprintf(fil, "\t\t},\n");
+				}
+				d = d->next_sibling;
+			}
+		} else {
+			if (ptr->children) {
+				fprintf(fil, "\t\t[0] = {\n");
+				fprintf(fil, "\t\t\t.link_num = 0,\n");
+				fprintf(fil, "\t\t\t.dev = &%s,\n", ptr->name);
+				fprintf(fil, "\t\t\t.children = &%s,\n", ptr->children->name);
+				fprintf(fil, "\t\t\t.next = NULL,\n");
+				fprintf(fil, "\t\t},\n");
+			}
+		}
+		fprintf(fil, "\t};\n");
+	}
 	if ((ptr->type == chip) && (ptr->chiph_exists)) {
 		if (ptr->reg) {
 			fprintf(fil, "struct %s_config %s_info_%d\t= {\n", ptr->name_underscore, ptr->name_underscore, ptr->id);
Index: svn/src/mainboard/ibase/mb899/mptable.c
===================================================================
--- svn.orig/src/mainboard/ibase/mb899/mptable.c
+++ svn/src/mainboard/ibase/mb899/mptable.c
@@ -70,7 +70,7 @@ static void *smp_write_config_table(void
 	if (!riser)
 		riser = dev_find_device(0x3388, 0x0022, 0);
 	if (riser) {
-		riser_bus = riser->link[0].secondary;
+		riser_bus = riser->link_list->secondary;
 		printk(BIOS_SPEW, "Riser bus is %x\n", riser_bus);
 		max_pci_bus = riser_bus;
 	}
