Same conversion as with resources from static arrays to lists, except
there is no free list.

Converting resource arrays to lists reduced the size of each device
struct from 1092 to 228 bytes.

Converting link arrays to lists reduced the size of each device struct
from 228 to 68 bytes.

Signed-off-by: Myles Watson <mylesgw@gmail.com>
Acked-by: Stefan Reinauer <stepan@coresystems.de>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5626 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/devices/cardbus_device.c b/src/devices/cardbus_device.c
index d48939f..fab0a3a 100644
--- a/src/devices/cardbus_device.c
+++ b/src/devices/cardbus_device.c
@@ -158,7 +158,7 @@
 {
 	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 @@
 	.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,
 };
diff --git a/src/devices/device.c b/src/devices/device.c
index f6c7af4..2a05a30 100644
--- a/src/devices/device.c
+++ b/src/devices/device.c
@@ -66,7 +66,6 @@
 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 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 			 * 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 @@
 	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 @@
 			 * 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 @@
 	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 @@
 	}
 
 	/* 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 @@
 	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 @@
 		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 @@
 
 	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 @@
 	/* 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 @@
 	}
 
 	/* 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 @@
 
 	/* 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 @@
 			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;
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index 91a41af..c845ecd 100644
--- a/src/devices/device_util.c
+++ b/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 *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 @@
 {
 	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 *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 @@
 		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 @@
 	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 @@
 			/* 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 @@
 	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 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 @@
 
 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 @@
 		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 @@
 			  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 @@
 	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);
 	}
diff --git a/src/devices/oprom/yabel/device.c b/src/devices/oprom/yabel/device.c
index 8bfb1fd..7fdc438 100644
--- a/src/devices/oprom/yabel/device.c
+++ b/src/devices/oprom/yabel/device.c
@@ -45,7 +45,7 @@
 {
 	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;
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 4aed35d..e6cebca 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -551,15 +551,13 @@
 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 @@
 	/* 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 @@
 
 	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_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;
 }
 
diff --git a/src/devices/pcix_device.c b/src/devices/pcix_device.c
index d3af53e..0fcedd5 100644
--- a/src/devices/pcix_device.c
+++ b/src/devices/pcix_device.c
@@ -61,20 +61,11 @@
 	}
 }
 
-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 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;
 }
diff --git a/src/devices/root_device.c b/src/devices/root_device.c
index b9369bc..a77b5c8 100644
--- a/src/devices/root_device.c
+++ b/src/devices/root_device.c
@@ -75,17 +75,17 @@
 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 @@
 			}
  			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 @@
  */
 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);
 		}
 	}
diff --git a/src/devices/smbus_ops.c b/src/devices/smbus_ops.c
index b224281..4a61e87 100644
--- a/src/devices/smbus_ops.c
+++ b/src/devices/smbus_ops.c
@@ -58,7 +58,7 @@
 //		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));