diff --git a/src/arch/i386/boot/mpspec.c b/src/arch/i386/boot/mpspec.c index 93e6ae1727..57a10ac670 100644 --- a/src/arch/i386/boot/mpspec.c +++ b/src/arch/i386/boot/mpspec.c @@ -190,7 +190,6 @@ void smp_write_intsrc_pci_bridge(struct mp_config_table *mc, { struct device *child; - int linkn; int i; int srcbus; int slot; @@ -198,9 +197,8 @@ void smp_write_intsrc_pci_bridge(struct mp_config_table *mc, 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; diff --git a/src/cpu/amd/sc520/sc520.c b/src/cpu/amd/sc520/sc520.c index 4c93ebd295..400ba6e622 100644 --- a/src/cpu/amd/sc520/sc520.c +++ b/src/cpu/amd/sc520/sc520.c @@ -130,8 +130,8 @@ static void pci_domain_set_resources(device_t 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(device_t dev) idx = 10; ram_resource(dev, idx++, 0, tolmk); } - assign_resources(&dev->link[0]); + assign_resources(dev->link_list); } #if 0 diff --git a/src/devices/cardbus_device.c b/src/devices/cardbus_device.c index d48939fff4..fab0a3afc2 100644 --- a/src/devices/cardbus_device.c +++ b/src/devices/cardbus_device.c @@ -158,7 +158,7 @@ void cardbus_enable_resources(device_t dev) { 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_ops_bus = { .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 f6c7af48c0..2a05a30fc1 100644 --- a/src/devices/device.c +++ b/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, struct device_path *path) 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 *bus) 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 *bus) 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 *bus, struct resource *bridge, 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 *bus, struct resource *bridge, * 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 bus *bus, struct resource *bridge, 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 bus *bus, struct resource *bridge, * 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 device *dev, struct constraints* limits) 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 device *dev, struct constraints* limits) } /* 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 *busdev, unsigned int max) 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; diff --git a/src/devices/device_util.c b/src/devices/device_util.c index 91a41af757..c845ecd35d 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 *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 dev, unsigned index) { 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, struct resource *resource, const char 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 *bus, 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 *bus, /* 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 enable) 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 *root, int debug_level, int depth) 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 *root, int debug_level, int depth) 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, int debug_level, int depth, int linknum) 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 8bfb1fd0c6..7fdc438bbd 100644 --- a/src/devices/oprom/yabel/device.c +++ b/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; diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index 4aed35d501..e6cebcaae6 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -551,15 +551,13 @@ static void pci_set_resource(struct device *dev, struct resource *resource) 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 device *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 device *dev, unsigned int max, 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 device *dev, unsigned int max) */ 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 d3af53eed0..0fcedd5e45 100644 --- a/src/devices/pcix_device.c +++ b/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 dev, unsigned int max) 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 b9369bcd1d..a77b5c8b62 100644 --- a/src/devices/root_device.c +++ b/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 bus, unsigned int max) } 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 bus, unsigned int max) */ 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 b22428123e..4a61e87a98 100644 --- a/src/devices/smbus_ops.c +++ b/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)); diff --git a/src/drivers/generic/debug/debug_dev.c b/src/drivers/generic/debug/debug_dev.c index 5c5dc8b16e..60d610fe40 100644 --- a/src/drivers/generic/debug/debug_dev.c +++ b/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 device *dev) 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); } } diff --git a/src/drivers/i2c/i2cmux/i2cmux.c b/src/drivers/i2c/i2cmux/i2cmux.c index cd68a01ebf..14c52ccfd3 100644 --- a/src/drivers/i2c/i2cmux/i2cmux.c +++ b/src/drivers/i2c/i2cmux/i2cmux.c @@ -34,7 +34,7 @@ static struct device_operations i2cmux_operations = { static void enable_dev(struct device *dev) { - if(dev->links>0) + if(dev->link_list != NULL) dev->ops = &i2cmux_operations; } diff --git a/src/drivers/i2c/i2cmux2/i2cmux2.c b/src/drivers/i2c/i2cmux2/i2cmux2.c index 4d2eeb99e6..c0f8e70878 100644 --- a/src/drivers/i2c/i2cmux2/i2cmux2.c +++ b/src/drivers/i2c/i2cmux2/i2cmux2.c @@ -33,7 +33,7 @@ static struct device_operations i2cmux2_operations = { static void enable_dev(struct device *dev) { - if(dev->links>0) + if(dev->link_list != NULL) dev->ops = &i2cmux2_operations; } diff --git a/src/include/device/device.h b/src/include/device/device.h index 6ac2d10bfc..b6e7a7bac1 100644 --- a/src/include/device/device.h +++ b/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); diff --git a/src/mainboard/emulation/qemu-x86/northbridge.c b/src/mainboard/emulation/qemu-x86/northbridge.c index 7b84928883..f4a0cc2973 100644 --- a/src/mainboard/emulation/qemu-x86/northbridge.c +++ b/src/mainboard/emulation/qemu-x86/northbridge.c @@ -60,7 +60,7 @@ extern uint64_t high_tables_base, high_tables_size; 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(device_t dev) 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) diff --git a/src/mainboard/ibase/mb899/mptable.c b/src/mainboard/ibase/mb899/mptable.c index c1854ecad2..d582ec6526 100644 --- a/src/mainboard/ibase/mb899/mptable.c +++ b/src/mainboard/ibase/mb899/mptable.c @@ -70,7 +70,7 @@ static void *smp_write_config_table(void *v) 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; } diff --git a/src/mainboard/kontron/986lcd-m/mptable.c b/src/mainboard/kontron/986lcd-m/mptable.c index bdba295bfc..cfa7cb7cdc 100644 --- a/src/mainboard/kontron/986lcd-m/mptable.c +++ b/src/mainboard/kontron/986lcd-m/mptable.c @@ -70,7 +70,7 @@ static void *smp_write_config_table(void *v) 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; } diff --git a/src/mainboard/tyan/s2881/mainboard.c b/src/mainboard/tyan/s2881/mainboard.c index 773f2540a4..6c41839227 100644 --- a/src/mainboard/tyan/s2881/mainboard.c +++ b/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_t root, unsigned int max) { 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_t root, unsigned int max) * 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; diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index a25a8df4e8..253a209965 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -137,7 +137,7 @@ static void set_vga_enable_reg(u32 nodeid, u32 linkn) } -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 dev, u32 nodeid, u32 link, u32 sblink, 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 dev, u32 nodeid, u32 link, u32 sblink, 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 dev, u32 nodeid, u32 link, u32 sblink, 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 dev, u32 nodeid, u32 link, u32 sblink, /* 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 dev, u32 nodeid, u32 link, u32 sblink, */ #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 dev, u32 nodeid, u32 link, u32 sblink, #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 dev, u32 nodeid, u32 link, u32 sblink, 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 dev, u32 nodeid, u32 link, u32 sblink, 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 dev, u32 max) #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 dev, u32 max) 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(device_t dev, u32 nodeid, u32 link) 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_t dev, struct resource *resource, 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_t dev, struct resource *resource, /* 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, " ", - nodeid, link); + sprintf(buf, " ", + nodeid, link_num); report_resource_stored(dev, resource, buf); } @@ -553,18 +555,18 @@ extern device_t vga_pri; // the primary vga device, defined in device.c 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(device_t dev, unsigned nodeid) } /* 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(device_t dev) 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_resources(device_t dev) #if CONFIG_PCI_64BIT_PREF_MEM == 0 pci_domain_read_resources(dev); #else - unsigned link; + struct bus *link; struct resource *resource; - for(link=0; linklinks; 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_resources(device_t dev) 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_resources(device_t dev) #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_resources(device_t dev) #endif pci_tolm = 0xffffffffUL; - for(link = 0; linklinks; 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_resources(device_t dev) #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(device_t dev, u32 max) { 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(device_t dev, u32 max) #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(device_t dev, u32 max) 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) // first node #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, u32 max) 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, u32 max) #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, u32 max) 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, u32 max) /* 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; linklink[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, u32 max) 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) diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index b798b0bf42..227a02edf0 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/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 nodeid, u32 link, u32 sblink, 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, u32 nodeid, u32 link, u32 sblink, } 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, u32 nodeid, u32 link, u32 sblink, */ #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, u32 nodeid, u32 link, u32 sblink, #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, u32 nodeid, u32 link, u32 sblink, */ 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, u32 nodeid, u32 link, u32 sblink, 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, u32 nodeid, u32 link, u32 sblink, 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_t dev, unsigned max) #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(device_t dev, unsigned nodeid); 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 dev, struct resource *resource, unsigned /* 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 dev, struct resource *resource, unsigned 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 dev, struct resource *resource, unsigned 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, " ", - nodeid, link); + nodeid, link_num); report_resource_stored(dev, resource, buf); } @@ -479,18 +492,18 @@ extern device_t vga_pri; // the primary vga device, defined in device.c 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(device_t dev, unsigned nodeid) } /* 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(device_t dev, unsigned nodeid) 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 dev) 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(device_t dev) } #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(device_t dev) } #endif } - assign_resources(&dev->link[0]); + assign_resources(dev->link_list); } @@ -1078,7 +1090,7 @@ static u32 amdk8_domain_scan_bus(device_t dev, u32 max) 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_t dev, u32 max) 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_domain_ops = { .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, u32 max) } /* 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, u32 max) */ 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, u32 max) 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) diff --git a/src/northbridge/amd/gx1/northbridge.c b/src/northbridge/amd/gx1/northbridge.c index 1176744c87..8b60345b0d 100644 --- a/src/northbridge/amd/gx1/northbridge.c +++ b/src/northbridge/amd/gx1/northbridge.c @@ -115,8 +115,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/amd/gx2/northbridge.c b/src/northbridge/amd/gx2/northbridge.c index bb41fd057d..4846ac328f 100644 --- a/src/northbridge/amd/gx2/northbridge.c +++ b/src/northbridge/amd/gx2/northbridge.c @@ -303,11 +303,9 @@ static void set_resources(struct device *dev) 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(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/amd/lx/northbridge.c b/src/northbridge/amd/lx/northbridge.c index 8fd8d9ecd2..5202de21e8 100644 --- a/src/northbridge/amd/lx/northbridge.c +++ b/src/northbridge/amd/lx/northbridge.c @@ -318,7 +318,6 @@ static void northbridge_init(device_t dev) static void northbridge_set_resources(struct device *dev) { - unsigned link; uint8_t line; #if 0 @@ -331,9 +330,8 @@ static void northbridge_set_resources(struct device *dev) } #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(device_t 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(device_t 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) diff --git a/src/northbridge/intel/e7501/northbridge.c b/src/northbridge/intel/e7501/northbridge.c index a2e4b245ee..5db56dc482 100644 --- a/src/northbridge/intel/e7501/northbridge.c +++ b/src/northbridge/intel/e7501/northbridge.c @@ -58,8 +58,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/intel/e7520/northbridge.c b/src/northbridge/intel/e7520/northbridge.c index 02f7c45495..c0580bbe3e 100644 --- a/src/northbridge/intel/e7520/northbridge.c +++ b/src/northbridge/intel/e7520/northbridge.c @@ -62,7 +62,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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(device_t 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 __pci_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) diff --git a/src/northbridge/intel/e7525/northbridge.c b/src/northbridge/intel/e7525/northbridge.c index a227f22987..2af6c25ae8 100644 --- a/src/northbridge/intel/e7525/northbridge.c +++ b/src/northbridge/intel/e7525/northbridge.c @@ -62,7 +62,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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(device_t 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 __pci_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) diff --git a/src/northbridge/intel/i3100/northbridge.c b/src/northbridge/intel/i3100/northbridge.c index 0675aea6bc..482e6006a5 100644 --- a/src/northbridge/intel/i3100/northbridge.c +++ b/src/northbridge/intel/i3100/northbridge.c @@ -83,7 +83,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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(device_t 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 __pci_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) diff --git a/src/northbridge/intel/i3100/pciexp_porta_ep80579.c b/src/northbridge/intel/i3100/pciexp_porta_ep80579.c index 42f624aaf7..a17cb0b3f2 100644 --- a/src/northbridge/intel/i3100/pciexp_porta_ep80579.c +++ b/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); diff --git a/src/northbridge/intel/i440bx/northbridge.c b/src/northbridge/intel/i440bx/northbridge.c index 772ab1c8f3..c5f09344bc 100644 --- a/src/northbridge/intel/i440bx/northbridge.c +++ b/src/northbridge/intel/i440bx/northbridge.c @@ -82,8 +82,8 @@ static void i440bx_domain_set_resources(device_t 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; int idx; @@ -118,7 +118,7 @@ static void i440bx_domain_set_resources(device_t 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 = { @@ -131,7 +131,7 @@ static struct device_operations pci_domain_ops = { 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) diff --git a/src/northbridge/intel/i440lx/northbridge.c b/src/northbridge/intel/i440lx/northbridge.c index 7ebc002c72..7c41e59c19 100644 --- a/src/northbridge/intel/i440lx/northbridge.c +++ b/src/northbridge/intel/i440lx/northbridge.c @@ -110,8 +110,8 @@ static void i440lx_domain_set_resources(device_t 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; int idx; @@ -146,7 +146,7 @@ static void i440lx_domain_set_resources(device_t 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 = { @@ -159,7 +159,7 @@ static struct device_operations pci_domain_ops = { 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) diff --git a/src/northbridge/intel/i82810/northbridge.c b/src/northbridge/intel/i82810/northbridge.c index 5b68046e7e..612d6c0907 100644 --- a/src/northbridge/intel/i82810/northbridge.c +++ b/src/northbridge/intel/i82810/northbridge.c @@ -119,8 +119,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/intel/i82830/northbridge.c b/src/northbridge/intel/i82830/northbridge.c index eb21b7cbb7..a1a389388d 100644 --- a/src/northbridge/intel/i82830/northbridge.c +++ b/src/northbridge/intel/i82830/northbridge.c @@ -111,8 +111,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/intel/i855/northbridge.c b/src/northbridge/intel/i855/northbridge.c index 3495fb6cfb..0438d09d93 100644 --- a/src/northbridge/intel/i855/northbridge.c +++ b/src/northbridge/intel/i855/northbridge.c @@ -83,8 +83,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/intel/i945/northbridge.c b/src/northbridge/intel/i945/northbridge.c index 0812460cfe..81b61bda59 100644 --- a/src/northbridge/intel/i945/northbridge.c +++ b/src/northbridge/intel/i945/northbridge.c @@ -138,7 +138,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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 __pci_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) diff --git a/src/northbridge/via/cn400/northbridge.c b/src/northbridge/via/cn400/northbridge.c index 3fbc358de5..2974d23da7 100644 --- a/src/northbridge/via/cn400/northbridge.c +++ b/src/northbridge/via/cn400/northbridge.c @@ -233,7 +233,7 @@ static void cn400_domain_set_resources(device_t dev) 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(device_t dev) 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_bus(device_t dev, unsigned int max) { 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_domain_ops = { 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) diff --git a/src/northbridge/via/cn700/northbridge.c b/src/northbridge/via/cn700/northbridge.c index 445ecf2780..b122a5e2fe 100644 --- a/src/northbridge/via/cn700/northbridge.c +++ b/src/northbridge/via/cn700/northbridge.c @@ -157,7 +157,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/via/cx700/northbridge.c b/src/northbridge/via/cx700/northbridge.c index 6a69d434fb..3f5ed28120 100644 --- a/src/northbridge/via/cx700/northbridge.c +++ b/src/northbridge/via/cx700/northbridge.c @@ -87,7 +87,7 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/via/vt8601/northbridge.c b/src/northbridge/via/vt8601/northbridge.c index 8fca0eae2c..1f15b7026e 100644 --- a/src/northbridge/via/vt8601/northbridge.c +++ b/src/northbridge/via/vt8601/northbridge.c @@ -98,8 +98,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c index 7ba9cd6316..d7fff335fe 100644 --- a/src/northbridge/via/vt8623/northbridge.c +++ b/src/northbridge/via/vt8623/northbridge.c @@ -158,8 +158,8 @@ static void pci_domain_set_resources(device_t 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(device_t 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_domain_ops = { 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) diff --git a/src/northbridge/via/vx800/northbridge.c b/src/northbridge/via/vx800/northbridge.c index 37e559c026..ec978e878b 100644 --- a/src/northbridge/via/vx800/northbridge.c +++ b/src/northbridge/via/vx800/northbridge.c @@ -128,7 +128,7 @@ static void pci_domain_set_resources(device_t 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 frame buffer size to 32M for default, but /* 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_domain_ops = { 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) diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c index ae2c4cffcb..d258450a06 100644 --- a/src/southbridge/amd/amd8131/amd8131_bridge.c +++ b/src/southbridge/amd/amd8131/amd8131_bridge.c @@ -25,7 +25,7 @@ static void amd8131_walk_children(struct bus *bus, 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); } diff --git a/src/southbridge/amd/amd8132/amd8132_bridge.c b/src/southbridge/amd/amd8132/amd8132_bridge.c index 5bbc3dc5ba..2ce46cd16a 100644 --- a/src/southbridge/amd/amd8132/amd8132_bridge.c +++ b/src/southbridge/amd/amd8132/amd8132_bridge.c @@ -47,7 +47,7 @@ static void amd8132_walk_children(struct bus *bus, 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); } diff --git a/src/southbridge/amd/sb600/sb600_lpc.c b/src/southbridge/amd/sb600/sb600_lpc.c index 0653772385..fd06f4478d 100644 --- a/src/southbridge/amd/sb600/sb600_lpc.c +++ b/src/southbridge/amd/sb600/sb600_lpc.c @@ -106,7 +106,7 @@ static void sb600_lpc_read_resources(device_t 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_resources(device_t dev) 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 diff --git a/src/southbridge/amd/sb700/sb700_lpc.c b/src/southbridge/amd/sb700/sb700_lpc.c index ab0a5ba6cc..e8bfbfac5d 100644 --- a/src/southbridge/amd/sb700/sb700_lpc.c +++ b/src/southbridge/amd/sb700/sb700_lpc.c @@ -118,7 +118,7 @@ static void sb700_lpc_set_resources(struct device *dev) */ 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_resources(device_t dev) 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 diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c b/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c index a80f5d79d5..3a876de69e 100644 --- a/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c +++ b/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c @@ -67,14 +67,14 @@ static void bcm5785_lpc_read_resources(device_t dev) */ 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; diff --git a/src/southbridge/intel/i82801gx/i82801gx_pci.c b/src/southbridge/intel/i82801gx/i82801gx_pci.c index c4c22f0ae8..1bdc67ae86 100644 --- a/src/southbridge/intel/i82801gx/i82801gx_pci.c +++ b/src/southbridge/intel/i82801gx/i82801gx_pci.c @@ -100,10 +100,10 @@ static void ich_pci_bus_enable_resources(struct device *dev) /* 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); diff --git a/src/southbridge/intel/pxhd/pxhd_bridge.c b/src/southbridge/intel/pxhd/pxhd_bridge.c index bfce8b6087..1134f8f2f8 100644 --- a/src/southbridge/intel/pxhd/pxhd_bridge.c +++ b/src/southbridge/intel/pxhd/pxhd_bridge.c @@ -41,8 +41,7 @@ static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max) { 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(device_t dev, unsigned int max) 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); } diff --git a/src/southbridge/nvidia/ck804/ck804_lpc.c b/src/southbridge/nvidia/ck804/ck804_lpc.c index a6637cad1c..e626400557 100644 --- a/src/southbridge/nvidia/ck804/ck804_lpc.c +++ b/src/southbridge/nvidia/ck804/ck804_lpc.c @@ -231,15 +231,15 @@ static void ck804_lpc_read_resources(device_t 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; diff --git a/src/southbridge/nvidia/ck804/ck804_smbus.c b/src/southbridge/nvidia/ck804/ck804_smbus.c index 3d8c9cee77..cc75a10703 100644 --- a/src/southbridge/nvidia/ck804/ck804_smbus.c +++ b/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, uint8_t val) 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, uint8_t address) 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 dev, uint8_t address, uint8_t val) 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); } diff --git a/src/southbridge/nvidia/mcp55/mcp55_lpc.c b/src/southbridge/nvidia/mcp55/mcp55_lpc.c index 0f9a50ca4f..0d32cb8275 100644 --- a/src/southbridge/nvidia/mcp55/mcp55_lpc.c +++ b/src/southbridge/nvidia/mcp55/mcp55_lpc.c @@ -205,16 +205,16 @@ static void mcp55_lpc_read_resources(device_t 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; diff --git a/src/southbridge/nvidia/mcp55/mcp55_smbus.c b/src/southbridge/nvidia/mcp55/mcp55_smbus.c index fd28710d94..8e049a76a7 100644 --- a/src/southbridge/nvidia/mcp55/mcp55_smbus.c +++ b/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, uint8_t val) 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, uint8_t address) 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 dev, uint8_t address, uint8_t val) 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); } diff --git a/src/southbridge/sis/sis966/sis966_lpc.c b/src/southbridge/sis/sis966/sis966_lpc.c index a3b79f078a..3b620cac45 100644 --- a/src/southbridge/sis/sis966/sis966_lpc.c +++ b/src/southbridge/sis/sis966/sis966_lpc.c @@ -198,16 +198,16 @@ static void sis966_lpc_read_resources(device_t dev) */ 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; diff --git a/util/sconfig/main.c b/util/sconfig/main.c index a8441111db..83b1c7ce3c 100755 --- a/util/sconfig/main.c +++ b/util/sconfig/main.c @@ -278,10 +278,14 @@ void add_register(struct device *dev, char *name, char *val) { } 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 device *ptr) { 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 device *ptr) { 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 device *ptr) { } 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);