{
struct device *child;
- int linkn;
int i;
int srcbus;
int slot;
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;
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;
idx = 10;
ram_resource(dev, idx++, 0, tolmk);
}
- assign_resources(&dev->link[0]);
+ assign_resources(dev->link_list);
}
#if 0
{
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 |
.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,
};
device_t alloc_dev(struct bus *parent, struct device_path *path)
{
device_t dev, child;
- int link;
spin_lock(&dev_lock);
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;
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;
}
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 {
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)
* 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));
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)
* 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));
struct device *child;
struct resource *res;
struct resource *lim;
- int i;
+ struct bus *link;
printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
}
/* 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);
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) {
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);
}
/**
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;
/* 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;
}
}
/* 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) {
/* 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.");
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;
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;
}
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;
}
{
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);
{
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;
}
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,
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;
/* 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;
}
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;
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);
}
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. */
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",
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);
}
}
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);
}
{
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;
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);
}
/* 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);
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
*/
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;
}
}
}
-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)
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;
}
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);
}
}
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));
*/
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);
}
}
// 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));
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;
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);
}
}
static void enable_dev(struct device *dev)
{
- if(dev->links>0)
+ if(dev->link_list != NULL)
dev->ops = &i2cmux_operations;
}
static void enable_dev(struct device *dev)
{
- if(dev->links>0)
+ if(dev->link_list != NULL)
dev->ops = &i2cmux2_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 */
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:
/* 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;
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);
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;
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)
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;
}
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;
}
/* 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");
{
struct device_path path;
device_t dummy;
- unsigned link_i;
max = root_dev_scan_bus(root, 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;
}
-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?
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;
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);
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;
/* 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;
*/
#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
#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
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++;
{
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;
#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
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;
}
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);
}
}
}
u32 nodeid)
{
resource_t rbase, rend;
- unsigned reg, link;
+ unsigned reg, link_num;
char buf[50];
/* Make certain the resource has actually been set */
/* Get the register and link */
reg = resource->index & 0xfff; // 4k
- link = IOINDEX_LINK(resource->index);
+ link_num = IOINDEX_LINK(resource->index);
if (resource->flags & IORESOURCE_IO) {
- set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
- store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
+ set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
+ store_conf_io_addr(nodeid, link_num, reg, (resource->index >> 24), rbase>>8, rend>>8);
}
else if (resource->flags & IORESOURCE_MEM) {
- set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
- store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
+ set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
+ store_conf_mmio_addr(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8);
}
resource->flags |= IORESOURCE_STORED;
- sprintf(buf, " <node %02x link %02x>",
- nodeid, link);
+ sprintf(buf, " <node %x link %x>",
+ nodeid, link_num);
report_resource_stored(dev, resource, buf);
}
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;
}
/* 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 */
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);
}
#if CONFIG_PCI_64BIT_PREF_MEM == 0
pci_domain_read_resources(dev);
#else
- unsigned link;
+ struct bus *link;
struct resource *resource;
- for(link=0; link<dev->links; link++) {
+ for(link=dev->link_list; link; link = link->next) {
/* Initialize the system wide io space constraints */
- resource = new_resource(dev, 0|(link<<2));
+ resource = new_resource(dev, 0|(link->link_num<<2));
resource->base = 0x400;
resource->limit = 0xffffUL;
resource->flags = IORESOURCE_IO;
/* Initialize the system wide prefetchable memory resources constraints */
- resource = new_resource(dev, 1|(link<<2));
+ resource = new_resource(dev, 1|(link->link_num<<2));
resource->limit = 0xfcffffffffULL;
resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
/* Initialize the system wide memory resources constraints */
- resource = new_resource(dev, 2|(link<<2));
+ resource = new_resource(dev, 2|(link->link_num<<2));
resource->limit = 0xfcffffffffULL;
resource->flags = IORESOURCE_MEM;
}
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;
#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);
#endif
pci_tolm = 0xffffffffUL;
- for(link = 0; link<dev->links; link++) {
- pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
+ for(link = dev->link_list; link; link = link->next) {
+ pci_tolm = find_pci_tolm(link, pci_tolm);
}
// FIXME handle interleaved nodes. If you fix this here, please fix
#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);
}
}
}
{
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);
#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.
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);
}
#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;
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));
#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;
if(i>=32) {
busn--;
devn-=32;
- pbus = &(pci_domain->link[1]);
+ pbus = pci_domain->link_list->next);
}
#endif
/* Ok, We need to set the links for that device.
* otherwise the device under it will not be scanned
*/
- int link;
int linknum;
#if CONFIG_HT3_SUPPORT==1
linknum = 8;
#else
linknum = 4;
#endif
- if (cdb_dev->links < linknum) {
- for(link=cdb_dev->links; link<linknum; link++) {
- cdb_dev->link[link].link = link;
- cdb_dev->link[link].dev = cdb_dev;
- }
- cdb_dev->links = linknum;
- printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(cdb_dev), cdb_dev->links);
- }
+ add_more_links(cdb_dev, linknum);
}
cores_found = 0; // one core
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)
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)
{
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;
}
if (((config & 3) == 3) &&
(((config >> 4) & 7) == nodeid) &&
- (((config >> 8) & 3) == link)) {
+ (((config >> 8) & 3) == link_num)) {
break;
}
}
*/
#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
#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
*/
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
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);
{
static unsigned amdk8_scan_chains(device_t dev, unsigned max)
{
unsigned nodeid;
- unsigned link;
+ struct bus *link;
unsigned sblink = 0;
unsigned offset_unitid = 0;
#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;
}
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 */
/* 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;
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;
}
base |= 3;
limit &= 0x00000048;
limit |= (rend >> 8) & 0xffffff00;
- limit |= (link & 3) << 4;
+ limit |= (link_num & 3) << 4;
limit |= (nodeid & 7);
f1_write_config32(reg + 0x4, limit);
f1_write_config32(reg, base);
}
resource->flags |= IORESOURCE_STORED;
sprintf(buf, " <node %x link %x>",
- nodeid, link);
+ nodeid, link_num);
report_resource_stored(dev, resource, buf);
}
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;
}
/* 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;
static void amdk8_set_resources(device_t dev)
{
- unsigned nodeid, link;
+ unsigned nodeid;
+ struct bus *bus;
struct resource *res;
/* Find the nodeid */
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);
}
}
#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.
}
#endif
}
- assign_resources(&dev->link[0]);
+ assign_resources(dev->link_list);
}
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.
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);
}
.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;
}
/* 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;
*/
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);
}
}
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)
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;
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 = {
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)
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);
}
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;
ram_resource(dev, idx++, 0, tolmk);
}
#endif
- assign_resources(&dev->link[0]);
+ assign_resources(dev->link_list);
}
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)
static void northbridge_set_resources(struct device *dev)
{
- unsigned link;
uint8_t line;
#if 0
}
#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);
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
#endif
}
- assign_resources(&dev->link[0]);
+ assign_resources(dev->link_list);
}
static void pci_domain_enable(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)
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
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 = {
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)
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);
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
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)
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)
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);
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
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)
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)
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);
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
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)
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)
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);
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;
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 = {
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)
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;
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 = {
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)
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.
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 = {
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)
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;
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 */
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)
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);
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 = {
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)
/* 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",
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 */
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)
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);
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__);
}
{
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;
}
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)
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);
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 = {
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)
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);
/* 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 = {
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)
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;
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 = {
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)
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;
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 = {
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)
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);
/* 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 = {
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)
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);
}
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);
}
*/
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];
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
*/
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];
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
*/
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;
/* 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);
{
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) {
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);
}
*/
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;
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);
}
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);
}
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);
}
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);
}
*/
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;
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);
}
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);
}
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);
}
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);
}
*/
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;
}
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);
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");
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) {
}
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);