diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/agp_device.c | 29 | ||||
-rw-r--r-- | src/devices/cardbus_device.c | 46 | ||||
-rw-r--r-- | src/devices/device.c | 377 | ||||
-rw-r--r-- | src/devices/device_util.c | 333 | ||||
-rw-r--r-- | src/devices/hypertransport.c | 533 | ||||
-rw-r--r-- | src/devices/pci_device.c | 420 | ||||
-rw-r--r-- | src/devices/pci_ops.c | 81 | ||||
-rw-r--r-- | src/devices/pci_rom.c | 93 | ||||
-rw-r--r-- | src/devices/pciexp_device.c | 9 | ||||
-rw-r--r-- | src/devices/pcix_device.c | 3 | ||||
-rw-r--r-- | src/devices/pnp_device.c | 16 | ||||
-rw-r--r-- | src/devices/smbus_ops.c | 2 | ||||
-rw-r--r-- | src/include/device/device.h | 2 | ||||
-rw-r--r-- | src/include/device/pci.h | 1 | ||||
-rw-r--r-- | src/include/device/pci_ops.h | 24 |
15 files changed, 1049 insertions, 920 deletions
diff --git a/src/devices/agp_device.c b/src/devices/agp_device.c index 87c3a20082..7e510f8eee 100644 --- a/src/devices/agp_device.c +++ b/src/devices/agp_device.c @@ -26,27 +26,30 @@ static void agp_tune_dev(device_t dev) { - unsigned cap; + unsigned int cap; + cap = pci_find_capability(dev, PCI_CAP_ID_AGP); - if (!cap) { + if (!cap) return; - } - /* The OS is responsible for AGP tuning so do nothing here */ + + /* The OS is responsible for AGP tuning so do nothing here. */ } -unsigned int agp_scan_bus(struct bus *bus, - unsigned min_devfn, unsigned max_devfn, unsigned int max) +unsigned int agp_scan_bus(struct bus *bus, unsigned int min_devfn, + unsigned int max_devfn, unsigned int max) { 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)) - { + + for (child = bus->children; child; child = child->sibling) { + if ((child->path.pci.devfn < min_devfn) || + (child->path.pci.devfn > max_devfn)) { continue; } agp_tune_dev(child); } + return max; } @@ -55,7 +58,7 @@ unsigned int agp_scan_bridge(device_t dev, unsigned int max) return do_pci_scan_bridge(dev, max, agp_scan_bus); } -/** Default device operations for AGP bridges */ +/** Default device operations for AGP bridges. */ static struct pci_operations agp_bus_ops_pci = { .set_subsystem = 0, }; @@ -64,8 +67,8 @@ struct device_operations default_agp_ops_bus = { .read_resources = pci_bus_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, - .init = 0, - .scan_bus = agp_scan_bridge, + .init = 0, + .scan_bus = agp_scan_bridge, .enable = 0, .reset_bus = pci_bus_reset, .ops_pci = &agp_bus_ops_pci, diff --git a/src/devices/cardbus_device.c b/src/devices/cardbus_device.c index e3acf856ec..0b07e3458f 100644 --- a/src/devices/cardbus_device.c +++ b/src/devices/cardbus_device.c @@ -42,36 +42,32 @@ static void cardbus_record_bridge_resource(device_t dev, resource_t moving, resource_t min_size, unsigned int index, unsigned long type) { struct resource *resource; + unsigned long gran; + resource_t step; /* Initialize the constraints on the current bus. */ resource = NULL; - if (moving) { - unsigned long gran; - resource_t step; - - resource = new_resource(dev, index); - resource->size = 0; - gran = 0; - step = 1; - while ((moving & step) == 0) { - gran += 1; - step <<= 1; - } - resource->gran = gran; - resource->align = gran; - resource->limit = moving | (step - 1); - resource->flags = type; + if (!moving) + return; + + resource = new_resource(dev, index); + resource->size = 0; + gran = 0; + step = 1; + while ((moving & step) == 0) { + gran += 1; + step <<= 1; + } + resource->gran = gran; + resource->align = gran; + resource->limit = moving | (step - 1); + resource->flags = type; - /* - * Don't let the minimum size exceed what we - * can put in the resource. - */ - if ((min_size - 1) > resource->limit) - min_size = resource->limit + 1; + /* Don't let the minimum size exceed what we can put in the resource. */ + if ((min_size - 1) > resource->limit) + min_size = resource->limit + 1; - resource->size = min_size; - } - return; + resource->size = min_size; } static void cardbus_size_bridge_resource(device_t dev, unsigned int index) diff --git a/src/devices/device.c b/src/devices/device.c index d7335c95a1..4143f96d66 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -18,15 +18,18 @@ /* * (c) 1999--2000 Martin Mares <mj@suse.cz> */ -/* lots of mods by ron minnich (rminnich@lanl.gov), with - * the final architecture guidance from Tom Merritt (tjm@codegen.com) + +/* + * Lots of mods by Ron Minnich <rminnich@lanl.gov>, with + * the final architecture guidance from Tom Merritt <tjm@codegen.com>. + * * In particular, we changed from the one-pass original version to * Tom's recommended multiple-pass version. I wasn't sure about doing * it with multiple passes, until I actually started doing it and saw - * the wisdom of Tom's recommendations ... + * the wisdom of Tom's recommendations... * * Lots of cleanups by Eric Biederman to handle bridges, and to - * handle resource allocation for non-pci devices. + * handle resource allocation for non-PCI devices. */ #include <console/console.h> @@ -67,13 +70,12 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) spin_lock(&dev_lock); /* Find the last child of our parent. */ - for (child = parent->children; child && child->sibling; /* */ ) { + for (child = parent->children; child && child->sibling; /* */ ) child = child->sibling; - } dev = malloc(sizeof(*dev)); if (dev == 0) - die("DEV: out of memory.\n"); + die("alloc_dev(): out of memory.\n"); memset(dev, 0, sizeof(*dev)); memcpy(&dev->path, path, sizeof(*path)); @@ -83,11 +85,10 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) /* Add the new device to the list of children of the bus. */ dev->bus = parent; - if (child) { + if (child) child->sibling = dev; - } else { + else parent->children = dev; - } /* Append a new device to the global device list. * The list is used to find devices once everything is set up. @@ -130,12 +131,13 @@ static void read_resources(struct bus *bus) /* Walk through all devices and find which resources they need. */ for (curdev = bus->children; curdev; curdev = curdev->sibling) { struct bus *link; - if (!curdev->enabled) { + + if (!curdev->enabled) continue; - } + if (!curdev->ops || !curdev->ops->read_resources) { printk(BIOS_ERR, "%s missing read_resources\n", - dev_path(curdev)); + dev_path(curdev)); continue; } curdev->ops->read_resources(curdev); @@ -145,7 +147,7 @@ static void read_resources(struct bus *bus) read_resources(link); } printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n", - dev_path(bus->dev), bus->secondary, bus->link_num); + dev_path(bus->dev), bus->secondary, bus->link_num); } struct pick_largest_state { @@ -169,7 +171,7 @@ static void pick_largest_resource(void *gp, struct device *dev, return; } if (resource->flags & IORESOURCE_FIXED) - return; // Skip it. + return; /* Skip it. */ if (last && ((last->align < resource->align) || ((last->align == resource->align) && (last->size < resource->size)) || @@ -206,7 +208,7 @@ static struct device *largest_resource(struct bus *bus, } /** - * Compute allocate resources is the guts of the resource allocator. + * This function is the guts of the resource allocator. * * The problem. * - Allocate resource locations for every device. @@ -239,20 +241,20 @@ static struct device *largest_resource(struct bus *bus, * @return TODO */ static void compute_resources(struct bus *bus, struct resource *bridge, - unsigned long type_mask, unsigned long type) + unsigned long type_mask, unsigned long type) { struct device *dev; struct resource *resource; resource_t base; base = round(bridge->base, bridge->align); - printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx\n", - dev_path(bus->dev), __func__, + printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d" + " limit: %llx\n", dev_path(bus->dev), __func__, (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? - "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran, bridge->limit); + "prefmem" : "mem", base, bridge->size, bridge->align, + bridge->gran, bridge->limit); - /* For each child which is a bridge, compute_resource_needs. */ + /* For each child which is a bridge, compute the resource needs. */ for (dev = bus->children; dev; dev = dev->sibling) { struct resource *child_bridge; @@ -264,24 +266,28 @@ static void compute_resources(struct bus *bus, struct resource *bridge, child_bridge = child_bridge->next) { struct bus* link; - if (!(child_bridge->flags & IORESOURCE_BRIDGE) || - (child_bridge->flags & type_mask) != type) + if (!(child_bridge->flags & IORESOURCE_BRIDGE) + || (child_bridge->flags & type_mask) != type) continue; - /* Split prefetchable memory if combined. Many domains + /* + * Split prefetchable memory if combined. Many domains * use the same address space for prefetchable memory - * and non-prefetchable memory. Bridges below them - * need it separated. Add the PREFETCH flag to the - * type_mask and type. + * and non-prefetchable memory. Bridges below them need + * it separated. Add the PREFETCH flag to the type_mask + * and type. */ link = dev->link_list; while (link && link->link_num != IOINDEX_LINK(child_bridge->index)) link = link->next; - if (link == NULL) + + 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 & @@ -292,37 +298,37 @@ static void compute_resources(struct bus *bus, struct resource *bridge, /* Remember we haven't found anything yet. */ resource = NULL; - /* Walk through all the resources on the current bus and compute the - * amount of address space taken by them. Take granularity and + /* + * Walk through all the resources on the current bus and compute the + * amount of address space taken by them. Take granularity and * alignment into account. */ while ((dev = largest_resource(bus, &resource, type_mask, type))) { /* Size 0 resources can be skipped. */ - if (!resource->size) { + if (!resource->size) continue; - } /* Propagate the resource alignment to the bridge resource. */ - if (resource->align > bridge->align) { + if (resource->align > bridge->align) bridge->align = resource->align; - } /* Propagate the resource limit to the bridge register. */ - if (bridge->limit > resource->limit) { + if (bridge->limit > resource->limit) bridge->limit = resource->limit; - } /* Warn if it looks like APICs aren't declared. */ if ((resource->limit == 0xffffffff) && (resource->flags & IORESOURCE_ASSIGNED)) { - printk(BIOS_ERR, "Resource limit looks wrong! (no APIC?)\n"); - printk(BIOS_ERR, "%s %02lx limit %08Lx\n", dev_path(dev), - resource->index, resource->limit); + printk(BIOS_ERR, + "Resource limit looks wrong! (no APIC?)\n"); + printk(BIOS_ERR, "%s %02lx limit %08Lx\n", + dev_path(dev), resource->index, resource->limit); } if (resource->flags & IORESOURCE_IO) { - /* Don't allow potential aliases over the legacy PCI + /* + * Don't allow potential aliases over the legacy PCI * expansion card addresses. The legacy PCI decodes * only 10 bits, uses 0x100 - 0x3ff. Therefore, only * 0x00 - 0xff can be used out of each 0x400 block of @@ -331,7 +337,8 @@ static void compute_resources(struct bus *bus, struct resource *bridge, if ((base & 0x300) != 0) { base = (base & ~0x3ff) + 0x400; } - /* Don't allow allocations in the VGA I/O range. + /* + * Don't allow allocations in the VGA I/O range. * PCI has special cases for that. */ else if ((base >= 0x3b0) && (base <= 0x3df)) { @@ -344,73 +351,53 @@ static void compute_resources(struct bus *bus, struct resource *bridge, base += resource->size; printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n", - dev_path(dev), resource->index, - resource->base, - resource->base + resource->size - 1, - (resource->flags & IORESOURCE_IO) ? "io" : - (resource->flags & IORESOURCE_PREFETCH) ? - "prefmem" : "mem"); + dev_path(dev), resource->index, resource->base, + resource->base + resource->size - 1, + (resource->flags & IORESOURCE_IO) ? "io" : + (resource->flags & IORESOURCE_PREFETCH) ? + "prefmem" : "mem"); } - /* A pci bridge resource does not need to be a power - * of two size, but it does have a minimum granularity. - * Round the size up to that minimum granularity so we - * know not to place something else at an address postitively - * decoded by the bridge. + + /* + * A PCI bridge resource does not need to be a power of two size, but + * it does have a minimum granularity. Round the size up to that + * minimum granularity so we know not to place something else at an + * address postitively decoded by the bridge. */ bridge->size = round(base, bridge->gran) - round(bridge->base, bridge->align); - printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx done\n", - dev_path(bus->dev), __func__, - (bridge->flags & IORESOURCE_IO) ? "io" : - (bridge->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran, bridge->limit); + printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d" + " limit: %llx done\n", dev_path(bus->dev), __func__, + (bridge->flags & IORESOURCE_IO) ? "io" : + (bridge->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran, bridge->limit); } /** * This function is the second part of the resource allocator. * - * The problem. - * - Allocate resource locations for every device. - * - Don't overlap, and follow the rules of bridges. - * - Don't overlap with resources in fixed locations. - * - Be efficient so we don't have ugly strategies. - * - * The strategy. - * - Devices that have fixed addresses are the minority so don't - * worry about them too much. Instead only use part of the address - * space for devices with programmable addresses. This easily handles - * everything except bridges. - * - * - PCI devices are required to have their sizes and their alignments - * equal. In this case an optimal solution to the packing problem - * exists. Allocate all devices from highest alignment to least - * alignment or vice versa. Use this. - * - * - So we can handle more than PCI run two allocation passes on bridges. The - * first to see how large the resources are behind the bridge, and what - * their alignment requirements are. The second to assign a safe address to - * the devices behind the bridge. This allows us to treat a bridge as just - * a device with a couple of resources, and not need to special case it in - * the allocator. Also this allows handling of other types of bridges. + * See the compute_resources function for a more detailed explanation. * - * - This function assigns the resources a value. + * This function assigns the resources a value. * * @param bus The bus we are traversing. * @param bridge The bridge resource which must contain the bus' resources. * @param type_mask This value gets ANDed with the resource type. * @param type This value must match the result of the AND. + * + * @see compute_resources */ static void allocate_resources(struct bus *bus, struct resource *bridge, - unsigned long type_mask, unsigned long type) + unsigned long type_mask, unsigned long type) { struct device *dev; struct resource *resource; resource_t base; base = bridge->base; - printk(BIOS_SPEW, "%s %s_%s: base:%llx size:%llx align:%d gran:%d limit:%llx\n", - dev_path(bus->dev), __func__, + printk(BIOS_SPEW, "%s %s_%s: base:%llx size:%llx align:%d gran:%d " + "limit:%llx\n", dev_path(bus->dev), __func__, (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? "prefmem" : "mem", base, bridge->size, bridge->align, bridge->gran, bridge->limit); @@ -418,15 +405,15 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, /* Remember we haven't found anything yet. */ resource = NULL; - /* Walk through all the resources on the current bus and allocate them + /* + * Walk through all the resources on the current bus and allocate them * address space. */ while ((dev = largest_resource(bus, &resource, type_mask, type))) { /* Propagate the bridge limit to the resource register. */ - if (resource->limit > bridge->limit) { + if (resource->limit > bridge->limit) resource->limit = bridge->limit; - } /* Size 0 resources can be skipped. */ if (!resource->size) { @@ -437,7 +424,8 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, } if (resource->flags & IORESOURCE_IO) { - /* Don't allow potential aliases over the legacy PCI + /* + * Don't allow potential aliases over the legacy PCI * expansion card addresses. The legacy PCI decodes * only 10 bits, uses 0x100 - 0x3ff. Therefore, only * 0x00 - 0xff can be used out of each 0x400 block of @@ -446,7 +434,8 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, if ((base & 0x300) != 0) { base = (base & ~0x3ff) + 0x400; } - /* Don't allow allocations in the VGA I/O range. + /* + * Don't allow allocations in the VGA I/O range. * PCI has special cases for that. */ else if ((base >= 0x3b0) && (base <= 0x3df)) { @@ -464,36 +453,33 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, base += resource->size; } else { printk(BIOS_ERR, "!! Resource didn't fit !!\n"); - printk(BIOS_ERR, " aligned base %llx size %llx limit %llx\n", - round(base, resource->align), resource->size, - resource->limit); - printk(BIOS_ERR, " %llx needs to be <= %llx (limit)\n", - (round(base, resource->align) + + printk(BIOS_ERR, " aligned base %llx size %llx " + "limit %llx\n", round(base, resource->align), + resource->size, resource->limit); + printk(BIOS_ERR, " %llx needs to be <= %llx " + "(limit)\n", (round(base, resource->align) + resource->size) - 1, resource->limit); - printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx] %s\n", - (resource-> - flags & IORESOURCE_ASSIGNED) ? "Assigned: " : - "", dev_path(dev), resource->index, - resource->base, + printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]" + " %s\n", (resource->flags & IORESOURCE_ASSIGNED) + ? "Assigned: " : "", dev_path(dev), + resource->index, resource->base, resource->base + resource->size - 1, - (resource-> - flags & IORESOURCE_IO) ? "io" : (resource-> - flags & - IORESOURCE_PREFETCH) + (resource->flags & IORESOURCE_IO) ? "io" + : (resource->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem"); } printk(BIOS_SPEW, "%s%s %02lx * [0x%llx - 0x%llx] %s\n", (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: " - : "", - dev_path(dev), resource->index, resource->base, + : "", dev_path(dev), resource->index, resource->base, resource->size ? resource->base + resource->size - 1 : - resource->base, - (resource->flags & IORESOURCE_IO) ? "io" : - (resource->flags & IORESOURCE_PREFETCH) ? "prefmem" : - "mem"); + resource->base, (resource->flags & IORESOURCE_IO) + ? "io" : (resource->flags & IORESOURCE_PREFETCH) + ? "prefmem" : "mem"); } - /* A PCI bridge resource does not need to be a power of two size, but + + /* + * A PCI bridge resource does not need to be a power of two size, but * it does have a minimum granularity. Round the size up to that * minimum granularity so we know not to place something else at an * address positively decoded by the bridge. @@ -501,11 +487,11 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, bridge->flags |= IORESOURCE_ASSIGNED; - printk(BIOS_SPEW, "%s %s_%s: next_base: %llx size: %llx align: %d gran: %d done\n", - dev_path(bus->dev), __func__, + printk(BIOS_SPEW, "%s %s_%s: next_base: %llx size: %llx align: %d " + "gran: %d done\n", dev_path(bus->dev), __func__, (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? - "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran); + "prefmem" : "mem", base, bridge->size, bridge->align, + bridge->gran); /* For each child which is a bridge, allocate_resources. */ for (dev = bus->children; dev; dev = dev->sibling) { @@ -523,11 +509,12 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, (child_bridge->flags & type_mask) != type) continue; - /* Split prefetchable memory if combined. Many domains + /* + * Split prefetchable memory if combined. Many domains * use the same address space for prefetchable memory - * and non-prefetchable memory. Bridges below them - * need it separated. Add the PREFETCH flag to the - * type_mask and type. + * and non-prefetchable memory. Bridges below them need + * it separated. Add the PREFETCH flag to the type_mask + * and type. */ link = dev->link_list; while (link && link->link_num != @@ -537,6 +524,7 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, 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 & @@ -551,10 +539,10 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, #define MEM_MASK (IORESOURCE_MEM) #endif -#define IO_MASK (IORESOURCE_IO) +#define IO_MASK (IORESOURCE_IO) #define PREF_TYPE (IORESOURCE_PREFETCH | IORESOURCE_MEM) -#define MEM_TYPE (IORESOURCE_MEM) -#define IO_TYPE (IORESOURCE_IO) +#define MEM_TYPE (IORESOURCE_MEM) +#define IO_TYPE (IORESOURCE_IO) struct constraints { struct resource pref, io, mem; @@ -575,8 +563,8 @@ static void constrain_resources(struct device *dev, struct constraints* limits) continue; if (!res->size) { /* It makes no sense to have 0-sized, fixed resources.*/ - printk(BIOS_ERR, "skipping %s@%lx fixed resource, size=0!\n", - dev_path(dev), res->index); + printk(BIOS_ERR, "skipping %s@%lx fixed resource, " + "size=0!\n", dev_path(dev), res->index); continue; } @@ -590,29 +578,34 @@ static void constrain_resources(struct device *dev, struct constraints* limits) else continue; - /* Is it a fixed resource outside the current known region? - If so, we don't have to consider it - it will be handled - correctly and doesn't affect current region's limits */ - if (((res->base + res->size -1) < lim->base) || (res->base > lim->limit)) + /* + * Is it a fixed resource outside the current known region? + * If so, we don't have to consider it - it will be handled + * correctly and doesn't affect current region's limits. + */ + if (((res->base + res->size -1) < lim->base) + || (res->base > lim->limit)) continue; - /* Choose to be above or below fixed resources. This - * check is signed so that "negative" amounts of space - * are handled correctly. + /* + * Choose to be above or below fixed resources. This check is + * signed so that "negative" amounts of space are handled + * correctly. */ - if ((signed long long)(lim->limit - (res->base + res->size -1)) > - (signed long long)(res->base - lim->base)) + if ((signed long long)(lim->limit - (res->base + res->size -1)) + > (signed long long)(res->base - lim->base)) lim->base = res->base + res->size; else lim->limit = res->base -1; } /* Descend into every enabled child and look for fixed resources. */ - for (link = dev->link_list; link; link = link->next) - for (child = link->children; child; - child = child->sibling) + for (link = dev->link_list; link; link = link->next) { + for (child = link->children; child; child = child->sibling) { if (child->enabled) constrain_resources(child, limits); + } + } } static void avoid_fixed_resources(struct device *dev) @@ -621,8 +614,8 @@ static void avoid_fixed_resources(struct device *dev) struct resource *res; printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev)); - /* Initialize constraints to maximum size. */ + /* Initialize constraints to maximum size. */ limits.pref.base = 0; limits.pref.limit = 0xffffffffffffffffULL; limits.io.base = 0; @@ -635,7 +628,7 @@ static void avoid_fixed_resources(struct device *dev) if ((res->flags & IORESOURCE_FIXED)) continue; printk(BIOS_SPEW, "%s:@%s %02lx limit %08Lx\n", __func__, - dev_path(dev), res->index, res->limit); + dev_path(dev), res->index, res->limit); if ((res->flags & MEM_MASK) == PREF_TYPE && (res->limit < limits.pref.limit)) limits.pref.limit = res->limit; @@ -685,7 +678,7 @@ device_t vga_pri = 0; static void set_vga_bridge_bits(void) { /* - * FIXME: Modify set_vga_bridge so it is less PCI centric! + * FIXME: Modify set_vga_bridge() so it is less PCI centric! * This function knows too much about PCI stuff, it should be just * an iterator/visitor. */ @@ -693,28 +686,30 @@ static void set_vga_bridge_bits(void) /* FIXME: Handle the VGA palette snooping. */ struct device *dev, *vga, *vga_onboard, *vga_first, *vga_last; struct bus *bus; + bus = 0; vga = 0; vga_onboard = 0; vga_first = 0; vga_last = 0; + for (dev = all_devices; dev; dev = dev->next) { + if (!dev->enabled) continue; + if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) { if (!vga_first) { - if (dev->on_mainboard) { + if (dev->on_mainboard) vga_onboard = dev; - } else { + else vga_first = dev; - } } else { - if (dev->on_mainboard) { + if (dev->on_mainboard) vga_onboard = dev; - } else { + else vga_last = dev; - } } /* It isn't safe to enable other VGA cards. */ @@ -724,30 +719,31 @@ static void set_vga_bridge_bits(void) vga = vga_last; - if (!vga) { + if (!vga) vga = vga_first; - } + #if CONFIG_CONSOLE_VGA_ONBOARD_AT_FIRST == 1 - if (vga_onboard) // Will use on board VGA as pri. + if (vga_onboard) /* Will use onboard VGA as primary. */ #else - if (!vga) // Will use last add on adapter as pri. + if (!vga) /* Will use last add-on adapter as primary. */ #endif { vga = vga_onboard; } if (vga) { - /* VGA is first add on card or the only onboard VGA. */ + /* VGA is first add-on card or the only onboard VGA. */ printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga)); /* All legacy VGA cards have MEM & I/O space registers. */ vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO); vga_pri = vga; bus = vga->bus; } + /* Now walk up the bridges setting the VGA enable. */ while (bus) { printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n", - dev_path(bus->dev)); + dev_path(bus->dev)); bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA; bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus; } @@ -758,7 +754,7 @@ static void set_vga_bridge_bits(void) /** * Assign the computed resources to the devices on the bus. * - * Use the device specific set_resources method to store the computed + * Use the device specific set_resources() method to store the computed * resources to hardware. For bridge devices, the set_resources() method * has to recurse into every down stream buses. * @@ -773,21 +769,21 @@ 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_num); + dev_path(bus->dev), bus->secondary, bus->link_num); for (curdev = bus->children; curdev; curdev = curdev->sibling) { - if (!curdev->enabled || !curdev->resource_list) { + if (!curdev->enabled || !curdev->resource_list) continue; - } + if (!curdev->ops || !curdev->ops->set_resources) { printk(BIOS_ERR, "%s missing set_resources\n", - dev_path(curdev)); + dev_path(curdev)); continue; } curdev->ops->set_resources(curdev); } printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n", - dev_path(bus->dev), bus->secondary, bus->link_num); + dev_path(bus->dev), bus->secondary, bus->link_num); } /** @@ -808,15 +804,13 @@ static void enable_resources(struct bus *link) struct bus *c_link; for (dev = link->children; dev; dev = dev->sibling) { - if (dev->enabled && dev->ops && dev->ops->enable_resources) { + if (dev->enabled && dev->ops && dev->ops->enable_resources) dev->ops->enable_resources(dev); - } } for (dev = link->children; dev; dev = dev->sibling) { - for (c_link = dev->link_list; c_link; c_link = c_link->next) { + for (c_link = dev->link_list; c_link; c_link = c_link->next) enable_resources(c_link); - } } } @@ -851,6 +845,7 @@ unsigned int scan_bus(struct device *busdev, unsigned int max) { unsigned int new_max; int do_scan_bus; + if (!busdev || !busdev->enabled || !busdev->ops || !busdev->ops->scan_bus) { return max; @@ -863,11 +858,10 @@ unsigned int scan_bus(struct device *busdev, unsigned int max) do_scan_bus = 0; for (link = busdev->link_list; link; link = link->next) { if (link->reset_needed) { - if (reset_bus(link)) { + if (reset_bus(link)) do_scan_bus = 1; - } else { + else busdev->bus->reset_needed = 1; - } } } } @@ -877,19 +871,19 @@ unsigned int scan_bus(struct device *busdev, unsigned int max) /** * Determine the existence of devices and extend the device tree. * - * Most of the devices in the system are listed in the mainboard Config.lb + * Most of the devices in the system are listed in the mainboard devicetree.cb * file. The device structures for these devices are generated at compile * time by the config tool and are organized into the device tree. This * function determines if the devices created at compile time actually exist * in the physical system. * - * For devices in the physical system but not listed in the Config.lb file, + * For devices in the physical system but not listed in devicetree.cb, * the device structures have to be created at run time and attached to the * device tree. * - * This function starts from the root device 'dev_root', scan the buses in - * the system recursively, modify the device tree according to the result of - * the probe. + * This function starts from the root device 'dev_root', scans the buses in + * the system recursively, and modifies the device tree according to the + * result of the probe. * * This function has no idea how to scan and probe buses and devices at all. * It depends on the bus/device specific scan_bus() method to do it. The @@ -899,16 +893,18 @@ unsigned int scan_bus(struct device *busdev, unsigned int max) void dev_enumerate(void) { struct device *root; + printk(BIOS_INFO, "Enumerating buses...\n"); + root = &dev_root; - show_all_devs(BIOS_SPEW, "Before Device Enumeration."); + show_all_devs(BIOS_SPEW, "Before device enumeration."); printk(BIOS_SPEW, "Compare with tree...\n"); show_devs_tree(root, BIOS_SPEW, 0, 0); - if (root->chip_ops && root->chip_ops->enable_dev) { + if (root->chip_ops && root->chip_ops->enable_dev) root->chip_ops->enable_dev(root); - } + if (!root->ops || !root->ops->scan_bus) { printk(BIOS_ERR, "dev_root missing scan_bus operation"); return; @@ -944,7 +940,8 @@ void dev_configure(void) root = &dev_root; - /* Each domain should create resources which contain the entire address + /* + * Each domain should create resources which contain the entire address * space for IO, MEM, and PREFMEM resources in the domain. The * allocation of device resources will be done from this address space. */ @@ -966,17 +963,17 @@ void dev_configure(void) continue; if (res->flags & IORESOURCE_PREFETCH) { compute_resources(child->link_list, - res, MEM_MASK, PREF_TYPE); + res, MEM_MASK, PREF_TYPE); continue; } if (res->flags & IORESOURCE_MEM) { compute_resources(child->link_list, - res, MEM_MASK, MEM_TYPE); + res, MEM_MASK, MEM_TYPE); continue; } if (res->flags & IORESOURCE_IO) { compute_resources(child->link_list, - res, IO_MASK, IO_TYPE); + res, IO_MASK, IO_TYPE); continue; } } @@ -987,7 +984,8 @@ void dev_configure(void) 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 + /* + * Now we need to adjust the resources. MEM resources need to start at * the highest address managable. */ for (child = root->link_list->children; child; child = child->sibling) { @@ -1011,17 +1009,17 @@ void dev_configure(void) continue; if (res->flags & IORESOURCE_PREFETCH) { allocate_resources(child->link_list, - res, MEM_MASK, PREF_TYPE); + res, MEM_MASK, PREF_TYPE); continue; } if (res->flags & IORESOURCE_MEM) { allocate_resources(child->link_list, - res, MEM_MASK, MEM_TYPE); + res, MEM_MASK, MEM_TYPE); continue; } if (res->flags & IORESOURCE_IO) { allocate_resources(child->link_list, - res, IO_MASK, IO_TYPE); + res, IO_MASK, IO_TYPE); continue; } } @@ -1045,7 +1043,7 @@ void dev_enable(void) printk(BIOS_INFO, "Enabling resources...\n"); - /* now enable everything. */ + /* Now enable everything. */ for (link = dev_root.link_list; link; link = link->next) enable_resources(link); @@ -1055,17 +1053,16 @@ void dev_enable(void) /** * Initialize a specific device. * - * The parent should be initialized first to avoid having an ordering - * problem. This is done by calling the parent's init() - * method before its childrens' init() methods. + * The parent should be initialized first to avoid having an ordering problem. + * This is done by calling the parent's init() method before its childrens' + * init() methods. * * @param dev The device to be initialized. */ static void init_dev(struct device *dev) { - if (!dev->enabled) { + if (!dev->enabled) return; - } if (!dev->initialized && dev->ops && dev->ops->init) { if (dev->path.type == DEVICE_PATH_I2C) { @@ -1084,14 +1081,12 @@ static void init_link(struct bus *link) struct device *dev; struct bus *c_link; - for (dev = link->children; dev; dev = dev->sibling) { + for (dev = link->children; dev; dev = dev->sibling) init_dev(dev); - } for (dev = link->children; dev; dev = dev->sibling) { - for (c_link = dev->link_list; c_link; c_link = c_link->next) { + for (c_link = dev->link_list; c_link; c_link = c_link->next) init_link(c_link); - } } } @@ -1110,7 +1105,7 @@ void dev_initialize(void) /* First call the mainboard init. */ init_dev(&dev_root); - /* now initialize everything. */ + /* Now initialize everything. */ for (link = dev_root.link_list; link; link = link->next) init_link(link); diff --git a/src/devices/device_util.c b/src/devices/device_util.c index 8315ce4907..9081a36ea2 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -41,9 +41,8 @@ device_t find_dev_path(struct bus *parent, struct device_path *path) { device_t child; for (child = parent->children; child; child = child->sibling) { - if (path_eq(path, &child->path)) { + if (path_eq(path, &child->path)) break; - } } return child; } @@ -59,9 +58,8 @@ device_t alloc_find_dev(struct bus *parent, struct device_path *path) { device_t child; child = find_dev_path(parent, path); - if (!child) { + if (!child) child = alloc_dev(parent, path); - } return child; } @@ -79,8 +77,8 @@ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) result = 0; for (dev = all_devices; dev; dev = dev->next) { if ((dev->path.type == DEVICE_PATH_PCI) && - (dev->bus->secondary == bus) && - (dev->path.pci.devfn == devfn)) { + (dev->bus->secondary == bus) && + (dev->path.pci.devfn == devfn)) { result = dev; break; } @@ -97,18 +95,18 @@ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) */ struct device *dev_find_slot_on_smbus(unsigned int bus, unsigned int addr) { - struct device *dev, *result; + struct device *dev, *result; - result = 0; - for (dev = all_devices; dev; dev = dev->next) { - if ((dev->path.type == DEVICE_PATH_I2C) && - (dev->bus->secondary == bus) && - (dev->path.i2c.device == addr)) { - result = dev; - break; - } - } - return result; + result = 0; + for (dev = all_devices; dev; dev = dev->next) { + if ((dev->path.type == DEVICE_PATH_I2C) && + (dev->bus->secondary == bus) && + (dev->path.i2c.device == addr)) { + result = dev; + break; + } + } + return result; } /** @@ -116,21 +114,21 @@ struct device *dev_find_slot_on_smbus(unsigned int bus, unsigned int addr) * * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel). * @param device A PCI device ID. - * @param from Pointer to the device structure, used as a starting point - * in the linked list of all_devices, which can be 0 to start at the - * head of the list (i.e. all_devices). + * @param from Pointer to the device structure, used as a starting point in + * the linked list of all_devices, which can be 0 to start at the + * head of the list (i.e. all_devices). * @return Pointer to the device struct. */ -struct device *dev_find_device(unsigned int vendor, unsigned int device, - struct device *from) +struct device *dev_find_device(u16 vendor, u16 device, struct device *from) { if (!from) from = all_devices; else from = from->next; - while (from && (from->vendor != vendor || from->device != device)) { + + while (from && (from->vendor != vendor || from->device != device)) from = from->next; - } + return from; } @@ -138,9 +136,9 @@ struct device *dev_find_device(unsigned int vendor, unsigned int device, * Find a device of a given class. * * @param class Class of the device. - * @param from Pointer to the device structure, used as a starting point - * in the linked list of all_devices, which can be 0 to start at the - * head of the list (i.e. all_devices). + * @param from Pointer to the device structure, used as a starting point in + * the linked list of all_devices, which can be 0 to start at the + * head of the list (i.e. all_devices). * @return Pointer to the device struct. */ struct device *dev_find_class(unsigned int class, struct device *from) @@ -149,8 +147,10 @@ struct device *dev_find_class(unsigned int class, struct device *from) from = all_devices; else from = from->next; + while (from && (from->class & 0xffffff00) != class) from = from->next; + return from; } @@ -165,8 +165,7 @@ const char *dev_path(device_t dev) buffer[0] = '\0'; if (!dev) { memcpy(buffer, "<null>", 7); - } - else { + } else { switch(dev->path.type) { case DEVICE_PATH_ROOT: memcpy(buffer, "Root Device", 12); @@ -174,12 +173,15 @@ const char *dev_path(device_t dev) case DEVICE_PATH_PCI: #if CONFIG_PCI_BUS_SEGN_BITS sprintf(buffer, "PCI: %04x:%02x:%02x.%01x", - dev->bus->secondary>>8, dev->bus->secondary & 0xff, - PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn)); + dev->bus->secondary >> 8, + dev->bus->secondary & 0xff, + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); #else sprintf(buffer, "PCI: %02x:%02x.%01x", dev->bus->secondary, - PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn)); + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); #endif break; case DEVICE_PATH_PNP: @@ -210,7 +212,8 @@ const char *dev_path(device_t dev) sprintf(buffer, "CPU_BUS: %02x", dev->path.cpu_bus.id); break; default: - printk(BIOS_ERR, "Unknown device path type: %d\n", dev->path.type); + printk(BIOS_ERR, "Unknown device path type: %d\n", + dev->path.type); break; } } @@ -227,43 +230,47 @@ const char *bus_path(struct bus *bus) int path_eq(struct device_path *path1, struct device_path *path2) { int equal = 0; - if (path1->type == path2->type) { - switch(path1->type) { - case DEVICE_PATH_NONE: - break; - case DEVICE_PATH_ROOT: - equal = 1; - break; - case DEVICE_PATH_PCI: - equal = (path1->pci.devfn == path2->pci.devfn); - break; - case DEVICE_PATH_PNP: - equal = (path1->pnp.port == path2->pnp.port) && - (path1->pnp.device == path2->pnp.device); - break; - case DEVICE_PATH_I2C: - equal = (path1->i2c.device == path2->i2c.device); - break; - case DEVICE_PATH_APIC: - equal = (path1->apic.apic_id == path2->apic.apic_id); - break; - case DEVICE_PATH_PCI_DOMAIN: - equal = (path1->pci_domain.domain == path2->pci_domain.domain); - break; - case DEVICE_PATH_APIC_CLUSTER: - equal = (path1->apic_cluster.cluster == path2->apic_cluster.cluster); - break; - case DEVICE_PATH_CPU: - equal = (path1->cpu.id == path2->cpu.id); - break; - case DEVICE_PATH_CPU_BUS: - equal = (path1->cpu_bus.id == path2->cpu_bus.id); - break; - default: - printk(BIOS_ERR, "Uknown device type: %d\n", path1->type); - break; - } + + if (path1->type != path2->type) + return 0; + + switch (path1->type) { + case DEVICE_PATH_NONE: + break; + case DEVICE_PATH_ROOT: + equal = 1; + break; + case DEVICE_PATH_PCI: + equal = (path1->pci.devfn == path2->pci.devfn); + break; + case DEVICE_PATH_PNP: + equal = (path1->pnp.port == path2->pnp.port) && + (path1->pnp.device == path2->pnp.device); + break; + case DEVICE_PATH_I2C: + equal = (path1->i2c.device == path2->i2c.device); + break; + case DEVICE_PATH_APIC: + equal = (path1->apic.apic_id == path2->apic.apic_id); + break; + case DEVICE_PATH_PCI_DOMAIN: + equal = (path1->pci_domain.domain == path2->pci_domain.domain); + break; + case DEVICE_PATH_APIC_CLUSTER: + equal = (path1->apic_cluster.cluster + == path2->apic_cluster.cluster); + break; + case DEVICE_PATH_CPU: + equal = (path1->cpu.id == path2->cpu.id); + break; + case DEVICE_PATH_CPU_BUS: + equal = (path1->cpu_bus.id == path2->cpu_bus.id); + break; + default: + printk(BIOS_ERR, "Uknown device type: %d\n", path1->type); + break; } + return equal; } @@ -276,6 +283,7 @@ static int allocate_more_resources(void) { int i; struct resource *new_res_list; + new_res_list = malloc(64 * sizeof(*new_res_list)); if (new_res_list == NULL) @@ -283,7 +291,7 @@ static int allocate_more_resources(void) memset(new_res_list, 0, 64 * sizeof(*new_res_list)); - for (i = 0; i < 64-1; i++) + for (i = 0; i < 64 - 1; i++) new_res_list[i].next = &new_res_list[i+1]; free_resources = new_res_list; @@ -305,12 +313,14 @@ static void free_resource(device_t dev, struct resource *res, prev->next = res->next; else dev->resource_list = res->next; + res->next = free_resources; free_resources = res; } /** * See if we have unused but allocated resource structures. + * * If so remove the allocation. * * @param dev The device to find the resource on. @@ -318,6 +328,7 @@ static void free_resource(device_t dev, struct resource *res, 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) { next = res->next; @@ -344,6 +355,7 @@ struct resource *probe_resource(device_t dev, unsigned index) if (res->index == index) break; } + return res; } @@ -361,10 +373,10 @@ struct resource *new_resource(device_t dev, unsigned index) { struct resource *resource, *tail; - /* First move all of the free resources to the end */ + /* First move all of the free resources to the end. */ compact_resources(dev); - /* See if there is a resource with the appropriate index */ + /* See if there is a resource with the appropriate index. */ resource = probe_resource(dev, index); if (!resource) { if (free_resources == NULL && !allocate_more_resources()) @@ -378,11 +390,12 @@ struct resource *new_resource(device_t dev, unsigned index) if (tail) { while (tail->next) tail = tail->next; tail->next = resource; - } - else + } else { dev->resource_list = resource; + } } - /* Initialize the resource values */ + + /* Initialize the resource values. */ if (!(resource->flags & IORESOURCE_FIXED)) { resource->flags = 0; resource->base = 0; @@ -407,17 +420,16 @@ struct resource *find_resource(device_t dev, unsigned index) { struct resource *resource; - /* See if there is a resource with the appropriate index */ + /* See if there is a resource with the appropriate index. */ resource = probe_resource(dev, index); if (!resource) { printk(BIOS_EMERG, "%s missing resource: %02x\n", - dev_path(dev), index); + dev_path(dev), index); die(""); } return resource; } - /** * Round a number up to the next multiple of gran. * @@ -458,16 +470,18 @@ static resource_t align_down(resource_t val, unsigned long gran) resource_t resource_end(struct resource *resource) { resource_t base, end; - /* get the base address */ + + /* Get the base address. */ base = resource->base; - /* For a non bridge resource granularity and alignment are the same. + /* + * For a non bridge resource granularity and alignment are the same. * For a bridge resource align is the largest needed alignment below - * the bridge. While the granularity is simply how many low bits of the - * address cannot be set. + * the bridge. While the granularity is simply how many low bits of + * the address cannot be set. */ - /* Get the end (rounded up) */ + /* Get the end (rounded up). */ end = base + align_up(resource->size, resource->gran) - 1; return end; @@ -498,14 +512,14 @@ const char *resource_type(struct resource *resource) { static char buffer[RESOURCE_TYPE_MAX]; sprintf(buffer, "%s%s%s%s", - ((resource->flags & IORESOURCE_READONLY)? "ro": ""), - ((resource->flags & IORESOURCE_PREFETCH)? "pref":""), - ((resource->flags == 0)? "unused": - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_DRQ)? "drq": - (resource->flags & IORESOURCE_IRQ)? "irq": - (resource->flags & IORESOURCE_MEM)? "mem":"??????"), - ((resource->flags & IORESOURCE_PCI64)?"64":"")); + ((resource->flags & IORESOURCE_READONLY) ? "ro" : ""), + ((resource->flags & IORESOURCE_PREFETCH) ? "pref" : ""), + ((resource->flags == 0) ? "unused" : + (resource->flags & IORESOURCE_IO) ? "io" : + (resource->flags & IORESOURCE_DRQ) ? "drq" : + (resource->flags & IORESOURCE_IRQ) ? "irq" : + (resource->flags & IORESOURCE_MEM) ? "mem" : "??????"), + ((resource->flags & IORESOURCE_PCI64) ? "64" : "")); return buffer; } @@ -519,52 +533,58 @@ const char *resource_type(struct resource *resource) void report_resource_stored(device_t dev, struct resource *resource, const char *comment) { - if (resource->flags & IORESOURCE_STORED) { - char buf[10]; - unsigned long long base, end; - base = resource->base; - end = resource_end(resource); - buf[0] = '\0'; - if (resource->flags & IORESOURCE_PCI_BRIDGE) { + char buf[10]; + unsigned long long base, end; + + if (!(resource->flags & IORESOURCE_STORED)) + return; + + base = resource->base; + end = resource_end(resource); + 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_list->secondary & 0xff); + sprintf(buf, "bus %04x:%02x ", dev->bus->secondary >> 8, + dev->link_list->secondary & 0xff); #else - sprintf(buf, "bus %02x ", dev->link_list->secondary); + sprintf(buf, "bus %02x ", dev->link_list->secondary); #endif - } - printk(BIOS_DEBUG, - "%s %02lx <- [0x%010Lx - 0x%010Lx] size 0x%08Lx gran 0x%02x %s%s%s\n", - dev_path(dev), - resource->index, - base, end, - resource->size, resource->gran, - buf, - resource_type(resource), - comment); } + printk(BIOS_DEBUG, "%s %02lx <- [0x%010Lx - 0x%010Lx] size 0x%08Lx " + "gran 0x%02x %s%s%s\n", dev_path(dev), resource->index, + base, end, resource->size, resource->gran, buf, + resource_type(resource), comment); } -void search_bus_resources(struct bus *bus, - unsigned long type_mask, unsigned long type, - resource_search_t search, void *gp) +void search_bus_resources(struct bus *bus, unsigned long type_mask, + unsigned long type, resource_search_t search, + void *gp) { struct device *curdev; + for (curdev = bus->children; curdev; curdev = curdev->sibling) { struct resource *res; - /* Ignore disabled devices */ - if (!curdev->enabled) continue; + + /* Ignore disabled devices. */ + if (!curdev->enabled) + continue; + 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) { + /* 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 it is a subtractive resource recurse. */ if (res->flags & IORESOURCE_SUBTRACTIVE) { struct bus * subbus; - for (subbus = curdev->link_list; subbus; subbus = subbus->next) - if (subbus->link_num == 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); + search_bus_resources(subbus, type_mask, type, + search, gp); continue; } search(gp, curdev, res); @@ -572,24 +592,27 @@ void search_bus_resources(struct bus *bus, } } -void search_global_resources( - unsigned long type_mask, unsigned long type, - resource_search_t search, void *gp) +void search_global_resources(unsigned long type_mask, unsigned long type, + resource_search_t search, void *gp) { struct device *curdev; + for (curdev = all_devices; curdev; curdev = curdev->next) { struct resource *res; - /* Ignore disabled devices */ - if (!curdev->enabled) continue; + + /* Ignore disabled devices. */ + if (!curdev->enabled) + continue; + 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) { + /* If it isn't the right kind of resource ignore it. */ + if ((res->flags & type_mask) != type) continue; - } - /* If it is a subtractive resource ignore it */ - if (res->flags & IORESOURCE_SUBTRACTIVE) { + + /* If it is a subtractive resource ignore it. */ + if (res->flags & IORESOURCE_SUBTRACTIVE) continue; - } + search(gp, curdev, res); } } @@ -597,14 +620,13 @@ void search_global_resources( void dev_set_enabled(device_t dev, int enable) { - if (dev->enabled == enable) { + if (dev->enabled == enable) return; - } + dev->enabled = enable; if (dev->ops && dev->ops->enable) { dev->ops->enable(dev); - } - else if (dev->chip_ops && dev->chip_ops->enable_dev) { + } else if (dev->chip_ops && dev->chip_ops->enable_dev) { dev->chip_ops->enable_dev(dev); } } @@ -612,11 +634,11 @@ 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) { struct bus *link; - for (link = child->link_list; link; link = link->next) { + for (link = child->link_list; link; link = link->next) disable_children(link); - } dev_set_enabled(child, 0); } } @@ -640,12 +662,11 @@ static void resource_tree(struct device *root, int debug_level, int depth) 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", - indent, dev_path(root), res->base, - res->size, res->align, - res->gran, res->limit, - res->flags, res->index); + do_printk(debug_level, "%s%s resource base %llx size %llx " + "align %d gran %d limit %llx flags %lx index %lx\n", + indent, dev_path(root), res->base, res->size, + res->align, res->gran, res->limit, res->flags, + res->index); } for (link = root->link_list; link; link = link->next) { @@ -654,8 +675,7 @@ static void resource_tree(struct device *root, int debug_level, int depth) } } -void print_resource_tree(struct device * root, int debug_level, - const char *msg) +void print_resource_tree(struct device *root, int debug_level, const char *msg) { /* Bail if root is null. */ if (!root) { @@ -665,8 +685,9 @@ void print_resource_tree(struct device * root, int debug_level, /* Bail if not printing to screen. */ if (!do_printk(debug_level, "Show resources in subtree (%s)...%s\n", - dev_path(root), msg)) + dev_path(root), msg)) return; + resource_tree(root, debug_level, 0); } @@ -680,8 +701,10 @@ void show_devs_tree(struct device *dev, int debug_level, int depth, int linknum) 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 (link = dev->link_list; link; link = link->next) { for (sibling = link->children; sibling; sibling = sibling->sibling) @@ -701,7 +724,7 @@ void show_devs_subtree(struct device *root, int debug_level, const char *msg) { /* Bail if not printing to screen. */ if (!do_printk(debug_level, "Show all devs in subtree %s...%s\n", - dev_path(root), msg)) + dev_path(root), msg)) return; do_printk(debug_level, "%s\n", msg); show_devs_tree(root, debug_level, 0, -1); @@ -728,6 +751,7 @@ void show_one_resource(int debug_level, struct device *dev, base = resource->base; end = resource_end(resource); buf[0] = '\0'; + /* if (resource->flags & IORESOURCE_BRIDGE) { #if CONFIG_PCI_BUS_SEGN_BITS @@ -738,19 +762,18 @@ void show_one_resource(int debug_level, struct device *dev, #endif } */ - do_printk(debug_level, "%s %02lx <- [0x%010llx - 0x%010llx] " - "size 0x%08Lx gran 0x%02x %s%s%s\n", - dev_path(dev), resource->index, base, end, - resource->size, resource->gran, buf, - resource_type(resource), comment); + do_printk(debug_level, "%s %02lx <- [0x%010llx - 0x%010llx] " + "size 0x%08Lx gran 0x%02x %s%s%s\n", dev_path(dev), + resource->index, base, end, resource->size, resource->gran, + buf, resource_type(resource), comment); } void show_all_devs_resources(int debug_level, const char* msg) { struct device *dev; - if(!do_printk(debug_level, "Show all devs with resources...%s\n", msg)) + if (!do_printk(debug_level, "Show all devs with resources...%s\n", msg)) return; for (dev = all_devices; dev; dev = dev->next) { diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index 89a41d64fc..926729177e 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -44,35 +44,38 @@ static device_t ht_scan_get_devs(device_t *old_devices) { device_t first, last; + first = *old_devices; last = first; - /* Extract the chain of devices to (first through last) - * for the next hypertransport device. + + /* + * Extract the chain of devices to (first through last) for the next + * hypertransport device. */ - while(last && last->sibling && - (last->sibling->path.type == DEVICE_PATH_PCI) && - (last->sibling->path.pci.devfn > last->path.pci.devfn)) + while (last && last->sibling && + (last->sibling->path.type == DEVICE_PATH_PCI) && + (last->sibling->path.pci.devfn > last->path.pci.devfn)) { last = last->sibling; } + if (first) { device_t child; - /* Unlink the chain from the list of old devices */ + + /* Unlink the chain from the list of old devices. */ *old_devices = last->sibling; last->sibling = 0; - /* Now add the device to the list of devices on the bus. - */ - /* Find the last child of our parent */ - for(child = first->bus->children; child && child->sibling; ) { + /* Now add the device to the list of devices on the bus. */ + /* Find the last child of our parent. */ + for (child = first->bus->children; child && child->sibling; ) child = child->sibling; - } + /* Place the chain on the list of children of their parent. */ - if (child) { + if (child) child->sibling = first; - } else { + else first->bus->children = first; - } } return first; } @@ -80,35 +83,39 @@ static device_t ht_scan_get_devs(device_t *old_devices) #if OPT_HT_LINK == 1 static unsigned ht_read_freq_cap(device_t dev, unsigned pos) { - /* Handle bugs in valid hypertransport frequency reporting */ + /* Handle bugs in valid hypertransport frequency reporting. */ unsigned freq_cap; freq_cap = pci_read_config16(dev, pos); - freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */ + freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies. */ - /* AMD 8131 Errata 48 */ + /* AMD 8131 Errata 48. */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && - (dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) { + (dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) { freq_cap &= ~(1 << HT_FREQ_800Mhz); } - /* AMD 8151 Errata 23 */ + + /* AMD 8151 Errata 23. */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && - (dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) { + (dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) { freq_cap &= ~(1 << HT_FREQ_800Mhz); } - /* AMD K8 Unsupported 1Ghz? */ + + /* AMD K8 unsupported 1GHz? */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) { #if CONFIG_K8_HT_FREQ_1G_SUPPORT == 1 - #if CONFIG_K8_REV_F_SUPPORT == 0 - if (is_cpu_pre_e0()) { // only e0 later suupport 1GHz HT + +#if CONFIG_K8_REV_F_SUPPORT == 0 + /* Only e0 later suupport 1GHz HT. */ + if (is_cpu_pre_e0()) freq_cap &= ~(1 << HT_FREQ_1000Mhz); - } - #endif +#endif + #else freq_cap &= ~(1 << HT_FREQ_1000Mhz); #endif - } + return freq_cap; } #endif @@ -122,11 +129,11 @@ struct ht_link { static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos) { #if OPT_HT_LINK == 1 - static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 }; - static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 }; - unsigned present_width_cap, upstream_width_cap; - unsigned present_freq_cap, upstream_freq_cap; - unsigned ln_present_width_in, ln_upstream_width_in; + static const u8 link_width_to_pow2[] = { 3, 4, 0, 5, 1, 2, 0, 0 }; + static const u8 pow2_to_link_width[] = { 7, 4, 5, 0, 1, 3 }; + unsigned present_width_cap, upstream_width_cap; + unsigned present_freq_cap, upstream_freq_cap; + unsigned ln_present_width_in, ln_upstream_width_in; unsigned ln_present_width_out, ln_upstream_width_out; unsigned freq, old_freq; unsigned present_width, upstream_width, old_width; @@ -135,54 +142,60 @@ static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos) int reset_needed; int linkb_to_host; - /* Set the hypertransport link width and frequency */ + /* Set the hypertransport link width and frequency. */ reset_needed = 0; - /* See which side of the device our previous write to - * set the unitid came from. + /* + * See which side of the device our previous write to set the unitid + * came from. */ cur->dev = dev; cur->pos = pos; - linkb_to_host = (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1; + linkb_to_host = + (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1; + if (!linkb_to_host) { cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0; cur->config_off = PCI_HT_CAP_SLAVE_WIDTH0; cur->freq_off = PCI_HT_CAP_SLAVE_FREQ0; cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0; - } - else { + } else { cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1; cur->config_off = PCI_HT_CAP_SLAVE_WIDTH1; cur->freq_off = PCI_HT_CAP_SLAVE_FREQ1; cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; } -#if OPT_HT_LINK == 1 - /* Read the capabilities */ - present_freq_cap = ht_read_freq_cap(cur->dev, cur->pos + cur->freq_cap_off); - upstream_freq_cap = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off); - present_width_cap = pci_read_config8(cur->dev, cur->pos + cur->config_off); - upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off); - /* Calculate the highest useable frequency */ +#if OPT_HT_LINK == 1 + /* Read the capabilities. */ + present_freq_cap = + ht_read_freq_cap(cur->dev, cur->pos + cur->freq_cap_off); + upstream_freq_cap = + ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off); + present_width_cap = + pci_read_config8(cur->dev, cur->pos + cur->config_off); + upstream_width_cap = + pci_read_config8(prev->dev, prev->pos + prev->config_off); + + /* Calculate the highest useable frequency. */ freq = log2(present_freq_cap & upstream_freq_cap); - /* Calculate the highest width */ + /* Calculate the highest width. */ ln_upstream_width_in = link_width_to_pow2[upstream_width_cap & 7]; ln_present_width_out = link_width_to_pow2[(present_width_cap >> 4) & 7]; - if (ln_upstream_width_in > ln_present_width_out) { + if (ln_upstream_width_in > ln_present_width_out) ln_upstream_width_in = ln_present_width_out; - } upstream_width = pow2_to_link_width[ln_upstream_width_in]; present_width = pow2_to_link_width[ln_upstream_width_in] << 4; - ln_upstream_width_out = link_width_to_pow2[(upstream_width_cap >> 4) & 7]; - ln_present_width_in = link_width_to_pow2[present_width_cap & 7]; - if (ln_upstream_width_out > ln_present_width_in) { + ln_upstream_width_out = + link_width_to_pow2[(upstream_width_cap >> 4) & 7]; + ln_present_width_in = link_width_to_pow2[present_width_cap & 7]; + if (ln_upstream_width_out > ln_present_width_in) ln_upstream_width_out = ln_present_width_in; - } upstream_width |= pow2_to_link_width[ln_upstream_width_out] << 4; present_width |= pow2_to_link_width[ln_upstream_width_out]; - /* Set the current device */ + /* Set the current device. */ old_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off); old_freq &= 0x0f; if (freq != old_freq) { @@ -193,55 +206,68 @@ static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos) new_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off); new_freq &= 0x0f; if (new_freq != freq) { - printk(BIOS_ERR, "%s Hypertransport frequency would not set wanted: %x got: %x\n", - dev_path(dev), freq, new_freq); + printk(BIOS_ERR, "%s Hypertransport frequency would " + "not set. Wanted: %x, got: %x\n", + dev_path(dev), freq, new_freq); } } old_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1); if (present_width != old_width) { unsigned new_width; pci_write_config8(cur->dev, cur->pos + cur->config_off + 1, - present_width); + present_width); reset_needed = 1; - printk(BIOS_SPEW, "HyperT widthP old %x new %x\n",old_width, present_width); - new_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1); + printk(BIOS_SPEW, "HyperT widthP old %x new %x\n", + old_width, present_width); + new_width = pci_read_config8(cur->dev, + cur->pos + cur->config_off + 1); if (new_width != present_width) { - printk(BIOS_ERR, "%s Hypertransport width would not set wanted: %x got: %x\n", - dev_path(dev), present_width, new_width); + printk(BIOS_ERR, "%s Hypertransport width would not " + "set. Wanted: %x, got: %x\n", + dev_path(dev), present_width, new_width); } } - /* Set the upstream device */ + /* Set the upstream device. */ old_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off); old_freq &= 0x0f; if (freq != old_freq) { unsigned new_freq; pci_write_config8(prev->dev, prev->pos + prev->freq_off, freq); reset_needed = 1; - printk(BIOS_SPEW, "HyperT freqU old %x new %x\n", old_freq, freq); - new_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off); + printk(BIOS_SPEW, "HyperT freqU old %x new %x\n", + old_freq, freq); + new_freq = + pci_read_config8(prev->dev, prev->pos + prev->freq_off); new_freq &= 0x0f; if (new_freq != freq) { - printk(BIOS_ERR, "%s Hypertransport frequency would not set wanted: %x got: %x\n", - dev_path(prev->dev), freq, new_freq); + printk(BIOS_ERR, "%s Hypertransport frequency would " + "not set. Wanted: %x, got: %x\n", + dev_path(prev->dev), freq, new_freq); } } - old_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1); + old_width = + pci_read_config8(prev->dev, prev->pos + prev->config_off + 1); if (upstream_width != old_width) { unsigned new_width; - pci_write_config8(prev->dev, prev->pos + prev->config_off + 1, upstream_width); + pci_write_config8(prev->dev, prev->pos + prev->config_off + 1, + upstream_width); reset_needed = 1; - printk(BIOS_SPEW, "HyperT widthU old %x new %x\n", old_width, upstream_width); - new_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1); + printk(BIOS_SPEW, "HyperT widthU old %x new %x\n", old_width, + upstream_width); + new_width = pci_read_config8(prev->dev, + prev->pos + prev->config_off + 1); if (new_width != upstream_width) { - printk(BIOS_ERR, "%s Hypertransport width would not set wanted: %x got: %x\n", - dev_path(prev->dev), upstream_width, new_width); + printk(BIOS_ERR, "%s Hypertransport width would not " + "set. Wanted: %x, got: %x\n", + dev_path(prev->dev), upstream_width, new_width); } } #endif - /* Remember the current link as the previous link, - * But look at the other offsets. + /* + * Remember the current link as the previous link, but look at the + * other offsets. */ prev->dev = cur->dev; prev->pos = cur->pos; @@ -263,29 +289,32 @@ static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos) static unsigned ht_lookup_slave_capability(struct device *dev) { unsigned pos; + pos = 0; do { pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos); if (pos) { - unsigned flags; + u16 flags; flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); printk(BIOS_SPEW, "flags: 0x%04x\n", flags); if ((flags >> 13) == 0) { - /* Entry is a Slave secondary, success... */ + /* Entry is a slave secondary, success... */ break; } } - } while(pos); + } while (pos); + return pos; } -static void ht_collapse_early_enumeration(struct bus *bus, unsigned offset_unitid) +static void ht_collapse_early_enumeration(struct bus *bus, + unsigned offset_unitid) { unsigned int devfn; struct ht_link prev; - unsigned ctrl; + u16 ctrl; - /* Initialize the hypertransport enumeration state */ + /* Initialize the hypertransport enumeration state. */ prev.dev = bus->dev; prev.pos = bus->cap; prev.ctrl_off = PCI_HT_CAP_HOST_CTRL; @@ -293,303 +322,328 @@ static void ht_collapse_early_enumeration(struct bus *bus, unsigned offset_uniti prev.freq_off = PCI_HT_CAP_HOST_FREQ; prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP; - /* Wait until the link initialization is complete */ + /* Wait until the link initialization is complete. */ do { ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); - /* Is this the end of the hypertransport chain */ - if (ctrl & (1 << 6)) { + + /* Is this the end of the hypertransport chain? */ + if (ctrl & (1 << 6)) return; - } + /* Has the link failed? */ if (ctrl & (1 << 4)) { /* - * Either the link has failed, or we have - * a CRC error. - * Sometimes this can happen due to link - * retrain, so lets knock it down and see - * if its transient + * Either the link has failed, or we have a CRC error. + * Sometimes this can happen due to link retrain, so + * lets knock it down and see if its transient. */ - ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc - pci_write_config16(prev.dev, prev.pos + prev.ctrl_off, ctrl); - ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + ctrl |= ((1 << 4) | (1 << 8)); /* Link fail + CRC */ + pci_write_config16(prev.dev, prev.pos + prev.ctrl_off, + ctrl); + ctrl = pci_read_config16(prev.dev, + prev.pos + prev.ctrl_off); if (ctrl & ((1 << 4) | (1 << 8))) { - printk(BIOS_ALERT, "Detected error on Hypertransport Link\n"); + printk(BIOS_ALERT, "Detected error on " + "Hypertransport link\n"); return; } } - } while((ctrl & (1 << 5)) == 0); + } while ((ctrl & (1 << 5)) == 0); - //actually, only for one HT device HT chain, and unitid is 0 + /* Actually, only for one HT device HT chain, and unitid is 0. */ #if CONFIG_HT_CHAIN_UNITID_BASE == 0 - if(offset_unitid) { - return; - } + if (offset_unitid) + return; #endif - /* Check if is already collapsed */ - if((!offset_unitid)|| (offset_unitid && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0) && (CONFIG_HT_CHAIN_END_UNITID_BASE <CONFIG_HT_CHAIN_UNITID_BASE))))) { - struct device dummy; - uint32_t id; - dummy.bus = bus; - dummy.path.type = DEVICE_PATH_PCI; - dummy.path.pci.devfn = PCI_DEVFN(0, 0); - id = pci_read_config32(&dummy, PCI_VENDOR_ID); - if ( ! ( (id == 0xffffffff) || (id == 0x00000000) || - (id == 0x0000ffff) || (id == 0xffff0000) ) ) { - return; - } - } - - /* Spin through the devices and collapse any early - * hypertransport enumeration. - */ - for(devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) { + /* Check if is already collapsed. */ + if ((!offset_unitid) || (offset_unitid + && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0) + && (CONFIG_HT_CHAIN_END_UNITID_BASE + < CONFIG_HT_CHAIN_UNITID_BASE))))) { + + struct device dummy; + u32 id; + + dummy.bus = bus; + dummy.path.type = DEVICE_PATH_PCI; + dummy.path.pci.devfn = PCI_DEVFN(0, 0); + + id = pci_read_config32(&dummy, PCI_VENDOR_ID); + if (!((id == 0xffffffff) || (id == 0x00000000) + || (id == 0x0000ffff) || (id == 0xffff0000))) { + return; + } + } + + /* Spin through the devices and collapse any early HT enumeration. */ + for (devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) { struct device dummy; - uint32_t id; + u32 id; unsigned pos, flags; - dummy.bus = bus; - dummy.path.type = DEVICE_PATH_PCI; + + dummy.bus = bus; + dummy.path.type = DEVICE_PATH_PCI; dummy.path.pci.devfn = devfn; + id = pci_read_config32(&dummy, PCI_VENDOR_ID); - if ( (id == 0xffffffff) || (id == 0x00000000) || - (id == 0x0000ffff) || (id == 0xffff0000)) { + if ((id == 0xffffffff) || (id == 0x00000000) + || (id == 0x0000ffff) || (id == 0xffff0000)) { continue; } + dummy.vendor = id & 0xffff; dummy.device = (id >> 16) & 0xffff; dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE); + pos = ht_lookup_slave_capability(&dummy); - if (!pos){ + if (!pos) continue; - } - /* Clear the unitid */ + /* Clear the unitid. */ flags = pci_read_config16(&dummy, pos + PCI_CAP_FLAGS); flags &= ~0x1f; pci_write_config16(&dummy, pos + PCI_CAP_FLAGS, flags); printk(BIOS_SPEW, "Collapsing %s [%04x/%04x]\n", - dev_path(&dummy), dummy.vendor, dummy.device); + dev_path(&dummy), dummy.vendor, dummy.device); } } -unsigned int hypertransport_scan_chain(struct bus *bus, - unsigned min_devfn, unsigned max_devfn, unsigned int max, unsigned *ht_unitid_base, unsigned offset_unitid) +unsigned int hypertransport_scan_chain(struct bus *bus, unsigned min_devfn, + unsigned max_devfn, unsigned int max, + unsigned *ht_unitid_base, + unsigned offset_unitid) { - //even CONFIG_HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link - unsigned next_unitid, last_unitid; - device_t old_devices, dev, func; - unsigned min_unitid = (offset_unitid) ? CONFIG_HT_CHAIN_UNITID_BASE:1; + /* + * Even CONFIG_HT_CHAIN_UNITID_BASE == 0, we still can go through this + * function, because of end_of_chain check. Also, we need it to + * optimize link. + */ + unsigned int next_unitid, last_unitid, min_unitid, max_unitid; + device_t old_devices, dev, func, last_func = 0; struct ht_link prev; - device_t last_func = 0; int ht_dev_num = 0; - unsigned max_unitid; + + min_unitid = (offset_unitid) ? CONFIG_HT_CHAIN_UNITID_BASE : 1; #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20 - //let't record the device of last ht device, So we can set the Unitid to CONFIG_HT_CHAIN_END_UNITID_BASE - unsigned real_last_unitid=0; - uint8_t real_last_pos=0; - device_t real_last_dev=NULL; - unsigned end_used = 0; + /* + * Let's record the device of last HT device, so we can set the unitid + * to CONFIG_HT_CHAIN_END_UNITID_BASE. + */ + unsigned int real_last_unitid = 0, end_used = 0; + u8 real_last_pos = 0; + device_t real_last_dev = NULL; #endif - /* Restore the hypertransport chain to it's unitialized state */ + /* Restore the hypertransport chain to it's unitialized state. */ ht_collapse_early_enumeration(bus, offset_unitid); - /* See which static device nodes I have */ + /* See which static device nodes I have. */ old_devices = bus->children; bus->children = 0; - /* Initialize the hypertransport enumeration state */ + /* Initialize the hypertransport enumeration state. */ prev.dev = bus->dev; prev.pos = bus->cap; + prev.ctrl_off = PCI_HT_CAP_HOST_CTRL; prev.config_off = PCI_HT_CAP_HOST_WIDTH; prev.freq_off = PCI_HT_CAP_HOST_FREQ; prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP; - /* If present assign unitid to a hypertransport chain */ + /* If present, assign unitid to a hypertransport chain. */ last_unitid = min_unitid -1; max_unitid = next_unitid = min_unitid; do { - uint8_t pos; - uint16_t flags; - unsigned count, static_count; - unsigned ctrl; + u8 pos; + u16 flags, ctrl; + unsigned int count, static_count; last_unitid = next_unitid; - /* Wait until the link initialization is complete */ + /* Wait until the link initialization is complete. */ do { - ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + ctrl = pci_read_config16(prev.dev, + prev.pos + prev.ctrl_off); + /* End of chain? */ if (ctrl & (1 << 6)) - goto end_of_chain; // End of chain + goto end_of_chain; if (ctrl & ((1 << 4) | (1 << 8))) { /* - * Either the link has failed, or we have - * a CRC error. - * Sometimes this can happen due to link - * retrain, so lets knock it down and see - * if its transient + * Either the link has failed, or we have a CRC + * error. Sometimes this can happen due to link + * retrain, so lets knock it down and see if + * it's transient. */ - ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc - pci_write_config16(prev.dev, prev.pos + prev.ctrl_off, ctrl); - ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + ctrl |= ((1 << 4) | (1 <<8)); // Link fail + CRC + pci_write_config16(prev.dev, + prev.pos + prev.ctrl_off, ctrl); + ctrl = pci_read_config16(prev.dev, + prev.pos + prev.ctrl_off); if (ctrl & ((1 << 4) | (1 << 8))) { - printk(BIOS_ALERT, "Detected error on Hypertransport Link\n"); + printk(BIOS_ALERT, "Detected error on " + "hypertransport link\n"); goto end_of_chain; } } - } while((ctrl & (1 << 5)) == 0); + } while ((ctrl & (1 << 5)) == 0); - /* Get and setup the device_structure */ + /* Get and setup the device_structure. */ dev = ht_scan_get_devs(&old_devices); - /* See if a device is present and setup the - * device structure. - */ + /* See if a device is present and setup the device structure. */ dev = pci_probe_dev(dev, bus, 0); - if (!dev || !dev->enabled) { + if (!dev || !dev->enabled) break; - } - /* Find the hypertransport link capability */ + /* Find the hypertransport link capability. */ pos = ht_lookup_slave_capability(dev); if (pos == 0) { - printk(BIOS_ERR, "%s Hypertransport link capability not found", - dev_path(dev)); + printk(BIOS_ERR, "%s Hypertransport link capability " + "not found", dev_path(dev)); break; } - /* Update the Unitid of the current device */ + /* Update the unitid of the current device. */ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); - /* If the devices has a unitid set and is at devfn 0 we are done. - * This can happen with shadow hypertransport devices, - * or if we have reached the bottom of a - * hypertransport device chain. + /* + * If the devices has a unitid set and is at devfn 0 we are + * done. This can happen with shadow hypertransport devices, + * or if we have reached the bottom of a HT device chain. */ - if (flags & 0x1f) { + if (flags & 0x1f) break; - } - flags &= ~0x1f; /* mask out base Unit ID */ - count = (flags >> 5) & 0x1f; /* get unit count */ + flags &= ~0x1f; /* Mask out base Unit ID. */ + + count = (flags >> 5) & 0x1f; /* Het unit count. */ + #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20 - if(offset_unitid) { - if(next_unitid > (max_devfn>>3)) { // max_devfn will be (0x17<<3)|7 or (0x1f<<3)|7 - if(!end_used) { - next_unitid = CONFIG_HT_CHAIN_END_UNITID_BASE; + if (offset_unitid) { + /* max_devfn will be (0x17<<3)|7 or (0x1f<<3)|7. */ + if (next_unitid > (max_devfn >> 3)) { + if (!end_used) { + next_unitid = + CONFIG_HT_CHAIN_END_UNITID_BASE; end_used = 1; } else { goto end_of_chain; } } - } #endif - flags |= next_unitid & 0x1f; - pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); + flags |= next_unitid & 0x1f; + pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); - /* Update the Unitd id in the device structure */ + /* Update the unitid in the device structure. */ static_count = 1; - for(func = dev; func; func = func->sibling) { + for (func = dev; func; func = func->sibling) { func->path.pci.devfn += (next_unitid << 3); static_count = (func->path.pci.devfn >> 3) - - (dev->path.pci.devfn >> 3) + 1; + - (dev->path.pci.devfn >> 3) + 1; last_func = func; } - /* Compute the number of unitids consumed */ + + /* Compute the number of unitids consumed. */ printk(BIOS_SPEW, "%s count: %04x static_count: %04x\n", - dev_path(dev), count, static_count); - if (count < static_count) { + dev_path(dev), count, static_count); + if (count < static_count) count = static_count; - } - /* Update the Unitid of the next device */ + /* Update the unitid of the next device. */ ht_unitid_base[ht_dev_num] = next_unitid; ht_dev_num++; #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20 if (offset_unitid) { - real_last_pos = pos; + real_last_pos = pos; real_last_unitid = next_unitid; real_last_dev = dev; } #endif - next_unitid += count; - if (next_unitid > max_unitid) { + next_unitid += count; + if (next_unitid > max_unitid) max_unitid = next_unitid; - } - /* Setup the hypetransport link */ + /* Setup the hypetransport link. */ bus->reset_needed |= ht_setup_link(&prev, dev, pos); printk(BIOS_DEBUG, "%s [%04x/%04x] %s next_unitid: %04x\n", - dev_path(dev), - dev->vendor, dev->device, - (dev->enabled? "enabled": "disabled"), next_unitid); + dev_path(dev), dev->vendor, dev->device, + (dev->enabled? "enabled" : "disabled"), next_unitid); } while (last_unitid != next_unitid); - end_of_chain: + +end_of_chain: + #if OPT_HT_LINK == 1 - if(bus->reset_needed) { + if (bus->reset_needed) printk(BIOS_INFO, "HyperT reset needed\n"); - } - else { + else printk(BIOS_DEBUG, "HyperT reset not needed\n"); - } #endif #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20 - if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE) && !end_used) { - uint16_t flags; - flags = pci_read_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS); - flags &= ~0x1f; - flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f; - pci_write_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS, flags); - - for(func = real_last_dev; func; func = func->sibling) { - func->path.pci.devfn -= ((real_last_unitid - CONFIG_HT_CHAIN_END_UNITID_BASE) << 3); + if (offset_unitid && (ht_dev_num > 1) + && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE) + && !end_used) { + u16 flags; + flags = pci_read_config16(real_last_dev, + real_last_pos + PCI_CAP_FLAGS); + flags &= ~0x1f; + flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f; + pci_write_config16(real_last_dev, + real_last_pos + PCI_CAP_FLAGS, flags); + + for (func = real_last_dev; func; func = func->sibling) { + func->path.pci.devfn -= ((real_last_unitid + - CONFIG_HT_CHAIN_END_UNITID_BASE) << 3); last_func = func; - } + } - ht_unitid_base[ht_dev_num-1] = CONFIG_HT_CHAIN_END_UNITID_BASE; // update last one + /* Update last one. */ + ht_unitid_base[ht_dev_num-1] = CONFIG_HT_CHAIN_END_UNITID_BASE; printk(BIOS_DEBUG, " unitid: %04x --> %04x\n", - real_last_unitid, CONFIG_HT_CHAIN_END_UNITID_BASE); - - } + real_last_unitid, CONFIG_HT_CHAIN_END_UNITID_BASE); + } #endif next_unitid = max_unitid; - if (next_unitid > 0x20) { + if (next_unitid > 0x20) next_unitid = 0x20; - } - if( (bus->secondary == 0) && (next_unitid > 0x18)) { - next_unitid = 0x18; /* avoid K8 on bus 0 */ - } - /* Die if any leftover Static devices are are found. - * There's probably a problem in the Config.lb. + if ((bus->secondary == 0) && (next_unitid > 0x18)) + next_unitid = 0x18; /* Avoid K8 on bus 0. */ + + /* + * Die if any leftover static devices are are found. There's probably + * a problem in devicetree.cb. */ - if(old_devices) { + if (old_devices) { device_t left; - for(left = old_devices; left; left = left->sibling) { + for (left = old_devices; left; left = left->sibling) printk(BIOS_DEBUG, "%s\n", dev_path(left)); - } - printk(BIOS_ERR, "HT: Left over static devices. Check your Config.lb\n"); - if(last_func && !last_func->sibling) // put back the left over static device, and let pci_scan_bus disable it + + printk(BIOS_ERR, "HT: Leftover static devices. " + "Check your devicetree.cb\n"); + + /* + * Put back the leftover static device, and let pci_scan_bus() + * disable it. + */ + if (last_func && !last_func->sibling) last_func->sibling = old_devices; } - /* Now that nothing is overlapping it is safe to scan the - * children. - */ - max = pci_scan_bus(bus, 0x00, ((next_unitid-1) << 3)|7, max); + /* Now that nothing is overlapping it is safe to scan the children. */ + max = pci_scan_bus(bus, 0x00, ((next_unitid - 1) << 3) | 7, max); return max; } @@ -608,11 +662,12 @@ unsigned int hypertransport_scan_chain(struct bus *bus, * @return The maximum bus number found, after scanning all subordinate busses. */ static unsigned int hypertransport_scan_chain_x(struct bus *bus, - unsigned min_devfn, unsigned max_devfn, unsigned int max) + unsigned int min_devfn, unsigned int max_devfn, unsigned int max) { - unsigned ht_unitid_base[4]; - unsigned offset_unitid = 1; - return hypertransport_scan_chain(bus, min_devfn, max_devfn, max, ht_unitid_base, offset_unitid); + unsigned int ht_unitid_base[4]; + unsigned int offset_unitid = 1; + return hypertransport_scan_chain(bus, min_devfn, max_devfn, max, + ht_unitid_base, offset_unitid); } unsigned int ht_scan_bridge(struct device *dev, unsigned int max) @@ -629,8 +684,8 @@ struct device_operations default_ht_ops_bus = { .read_resources = pci_bus_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, - .init = 0, - .scan_bus = ht_scan_bridge, + .init = 0, + .scan_bus = ht_scan_bridge, .enable = 0, .reset_bus = pci_bus_reset, .ops_pci = &ht_bus_ops_pci, diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index ac799c5fec..01fd815f4d 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -56,6 +56,7 @@ u8 pci_moving_config8(struct device *dev, unsigned int reg) { u8 value, ones, zeroes; + value = pci_read_config8(dev, reg); pci_write_config8(dev, reg, 0xff); @@ -69,9 +70,10 @@ u8 pci_moving_config8(struct device *dev, unsigned int reg) return ones ^ zeroes; } -u16 pci_moving_config16(struct device * dev, unsigned int reg) +u16 pci_moving_config16(struct device *dev, unsigned int reg) { u16 value, ones, zeroes; + value = pci_read_config16(dev, reg); pci_write_config16(dev, reg, 0xffff); @@ -85,9 +87,10 @@ u16 pci_moving_config16(struct device * dev, unsigned int reg) return ones ^ zeroes; } -u32 pci_moving_config32(struct device * dev, unsigned int reg) +u32 pci_moving_config32(struct device *dev, unsigned int reg) { u32 value, ones, zeroes; + value = pci_read_config32(dev, reg); pci_write_config32(dev, reg, 0xffffffff); @@ -114,13 +117,13 @@ unsigned pci_find_next_capability(struct device *dev, unsigned cap, unsigned last) { unsigned pos = 0; - unsigned status; + u16 status; unsigned reps = 48; status = pci_read_config16(dev, PCI_STATUS); - if (!(status & PCI_STATUS_CAP_LIST)) { + if (!(status & PCI_STATUS_CAP_LIST)) return 0; - } + switch (dev->hdr_type & 0x7f) { case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_BRIDGE: @@ -132,22 +135,24 @@ unsigned pci_find_next_capability(struct device *dev, unsigned cap, default: return 0; } + pos = pci_read_config8(dev, pos); - while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */ + while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */ int this_cap; + pos &= ~3; this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID); - printk(BIOS_SPEW, "Capability: type 0x%02x @ 0x%02x\n", this_cap, - pos); - if (this_cap == 0xff) { + printk(BIOS_SPEW, "Capability: type 0x%02x @ 0x%02x\n", + this_cap, pos); + if (this_cap == 0xff) break; - } - if (!last && (this_cap == cap)) { + + if (!last && (this_cap == cap)) return pos; - } - if (last == pos) { + + if (last == pos) last = 0; - } + pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT); } return 0; @@ -199,6 +204,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) moving |= ((resource_t) pci_moving_config32(dev, index + 4)) << 32; } + /* Find the resource constraints. * Start by finding the bits that move. From there: * - Size is the least significant bit of the bits that move. @@ -217,20 +223,25 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) resource->limit = limit = moving | (resource->size - 1); } - /* Some broken hardware has read-only registers that do not + /* + * Some broken hardware has read-only registers that do not * really size correctly. - * Example: the Acer M7229 has BARs 1-4 normally read-only. + * + * Example: the Acer M7229 has BARs 1-4 normally read-only, * so BAR1 at offset 0x10 reads 0x1f1. If you size that register - * by writing 0xffffffff to it, it will read back as 0x1f1 -- a - * violation of the spec. - * We catch this case and ignore it by observing which bits move, - * This also catches the common case unimplemented registers + * by writing 0xffffffff to it, it will read back as 0x1f1 -- which + * is a violation of the spec. + * + * We catch this case and ignore it by observing which bits move. + * + * This also catches the common case of unimplemented registers * that always read back as 0. */ if (moving == 0) { if (value != 0) { - printk(BIOS_DEBUG, "%s register %02lx(%08lx), read-only ignoring it\n", - dev_path(dev), index, value); + printk(BIOS_DEBUG, "%s register %02lx(%08lx), " + "read-only ignoring it\n", + dev_path(dev), index, value); } resource->flags = 0; } else if (attr & PCI_BASE_ADDRESS_SPACE_IO) { @@ -243,9 +254,8 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) /* A Memory mapped base address. */ attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK; resource->flags |= IORESOURCE_MEM; - if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) { + if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) resource->flags |= IORESOURCE_PREFETCH; - } attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK; if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) { /* 32bit limit. */ @@ -265,10 +275,10 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) resource->flags = 0; } } + /* Don't let the limit exceed which bits can move. */ - if (resource->limit > limit) { + if (resource->limit > limit) resource->limit = limit; - } return resource; } @@ -315,8 +325,9 @@ static void pci_get_rom_resource(struct device *dev, unsigned long index) resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY; } else { if (value != 0) { - printk(BIOS_DEBUG, "%s register %02lx(%08lx), read-only ignoring it\n", - dev_path(dev), index, value); + printk(BIOS_DEBUG, "%s register %02lx(%08lx), " + "read-only ignoring it\n", + dev_path(dev), index, value); } resource->flags = 0; } @@ -346,27 +357,29 @@ static void pci_read_bases(struct device *dev, unsigned int howmany) static void pci_record_bridge_resource(struct device *dev, resource_t moving, unsigned index, unsigned long type) { - /* Initialize the constraints on the current bus. */ struct resource *resource; + unsigned long gran; + resource_t step; + resource = NULL; - if (moving) { - unsigned long gran; - resource_t step; - resource = new_resource(dev, index); - resource->size = 0; - gran = 0; - step = 1; - while ((moving & step) == 0) { - gran += 1; - step <<= 1; - } - resource->gran = gran; - resource->align = gran; - resource->limit = moving | (step - 1); - resource->flags = type | IORESOURCE_PCI_BRIDGE | - IORESOURCE_BRIDGE; + + if (!moving) + return; + + /* Initialize the constraints on the current bus. */ + resource = new_resource(dev, index); + resource->size = 0; + gran = 0; + step = 1; + while ((moving & step) == 0) { + gran += 1; + step <<= 1; } - return; + resource->gran = gran; + resource->align = gran; + resource->limit = moving | (step - 1); + resource->flags = type | IORESOURCE_PCI_BRIDGE | + IORESOURCE_BRIDGE; } static void pci_bridge_read_bases(struct device *dev) @@ -452,26 +465,23 @@ static void pci_set_resource(struct device *dev, struct resource *resource) /* Make certain the resource has actually been assigned a value. */ if (!(resource->flags & IORESOURCE_ASSIGNED)) { - printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not assigned\n", - dev_path(dev), resource->index, - resource_type(resource), resource->size); + printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not " + "assigned\n", dev_path(dev), resource->index, + resource_type(resource), resource->size); return; } /* If this resource is fixed don't worry about it. */ - if (resource->flags & IORESOURCE_FIXED) { + if (resource->flags & IORESOURCE_FIXED) return; - } /* If I have already stored this resource don't worry about it. */ - if (resource->flags & IORESOURCE_STORED) { + if (resource->flags & IORESOURCE_STORED) return; - } /* If the resource is subtractive don't worry about it. */ - if (resource->flags & IORESOURCE_SUBTRACTIVE) { + if (resource->flags & IORESOURCE_SUBTRACTIVE) return; - } /* Only handle PCI memory and I/O resources for now. */ if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO))) @@ -479,16 +489,14 @@ static void pci_set_resource(struct device *dev, struct resource *resource) /* Enable the resources in the command register. */ if (resource->size) { - if (resource->flags & IORESOURCE_MEM) { + if (resource->flags & IORESOURCE_MEM) dev->command |= PCI_COMMAND_MEMORY; - } - if (resource->flags & IORESOURCE_IO) { + if (resource->flags & IORESOURCE_IO) dev->command |= PCI_COMMAND_IO; - } - if (resource->flags & IORESOURCE_PCI_BRIDGE) { + if (resource->flags & IORESOURCE_PCI_BRIDGE) dev->command |= PCI_COMMAND_MASTER; - } } + /* Get the base address. */ base = resource->base; @@ -498,8 +506,9 @@ static void pci_set_resource(struct device *dev, struct resource *resource) /* Now store the resource. */ resource->flags |= IORESOURCE_STORED; - /* PCI Bridges have no enable bit. They are disabled if the base of - * the range is greater than the limit. If the size is zero, disable + /* + * PCI bridges have no enable bit. They are disabled if the base of + * the range is greater than the limit. If the size is zero, disable * by setting the base = limit and end = limit - 2^gran. */ if (resource->size == 0 && (resource->flags & IORESOURCE_PCI_BRIDGE)) { @@ -510,18 +519,18 @@ static void pci_set_resource(struct device *dev, struct resource *resource) if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) { unsigned long base_lo, base_hi; - /* Some chipsets allow us to set/clear the I/O bit - * (e.g. VIA 82c686a). So set it to be safe. + + /* + * Some chipsets allow us to set/clear the I/O bit + * (e.g. VIA 82C686A). So set it to be safe. */ base_lo = base & 0xffffffff; base_hi = (base >> 32) & 0xffffffff; - if (resource->flags & IORESOURCE_IO) { + if (resource->flags & IORESOURCE_IO) base_lo |= PCI_BASE_ADDRESS_SPACE_IO; - } pci_write_config32(dev, resource->index, base_lo); - if (resource->flags & IORESOURCE_PCI64) { + if (resource->flags & IORESOURCE_PCI64) pci_write_config32(dev, resource->index + 4, base_hi); - } } else if (resource->index == PCI_IO_BASE) { /* Set the I/O ranges. */ pci_write_config8(dev, PCI_IO_BASE, base >> 8); @@ -542,10 +551,10 @@ static void pci_set_resource(struct device *dev, struct resource *resource) /* Don't let me think I stored the resource. */ resource->flags &= ~IORESOURCE_STORED; printk(BIOS_ERR, "ERROR: invalid resource->index %lx\n", - resource->index); + resource->index); } + report_resource_stored(dev, resource, ""); - return; } void pci_dev_set_resources(struct device *dev) @@ -554,28 +563,26 @@ void pci_dev_set_resources(struct device *dev) struct bus *bus; u8 line; - for (res = dev->resource_list; res; res = res->next) { + for (res = dev->resource_list; res; res = res->next) pci_set_resource(dev, res); - } + for (bus = dev->link_list; bus; bus = bus->next) { - if (bus->children) { + if (bus->children) assign_resources(bus); - } } /* Set a default latency timer. */ pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40); /* Set a default secondary latency timer. */ - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) { + if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40); - } /* Zero the IRQ settings. */ line = pci_read_config8(dev, PCI_INTERRUPT_PIN); - if (line) { + if (line) pci_write_config8(dev, PCI_INTERRUPT_LINE, 0); - } + /* Set the cache line size, so far 64 bytes is good for everyone. */ pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2); } @@ -585,22 +592,23 @@ void pci_dev_enable_resources(struct device *dev) const struct pci_operations *ops; u16 command; - /* Set the subsystem vendor and device id for mainboard devices. */ + /* Set the subsystem vendor and device ID for mainboard devices. */ ops = ops_pci(dev); if (dev->on_mainboard && ops && ops->set_subsystem) { - printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n", - dev_path(dev), - CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID, - CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID); + printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n", dev_path(dev), + CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID, + CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID); ops->set_subsystem(dev, CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID, CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID); } command = pci_read_config16(dev, PCI_COMMAND); command |= dev->command; + /* v3 has * command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); // Error check. */ + printk(BIOS_DEBUG, "%s cmd <- %02x\n", dev_path(dev), command); pci_write_config16(dev, PCI_COMMAND, command); } @@ -609,14 +617,15 @@ void pci_bus_enable_resources(struct device *dev) { u16 ctrl; - /* Enable I/O in command register if there is VGA card + /* + * Enable I/O in command register if there is VGA card * connected with (even it does not claim I/O resource). */ 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_list->bridge_ctrl; - ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* Error check. */ + 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); @@ -625,11 +634,13 @@ void pci_bus_enable_resources(struct device *dev) void pci_bus_reset(struct bus *bus) { - unsigned ctl; + u16 ctl; + ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL); ctl |= PCI_BRIDGE_CTL_BUS_RESET; pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl); mdelay(10); + ctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl); delay(1); @@ -641,7 +652,7 @@ void pci_dev_set_subsystem(struct device *dev, unsigned vendor, unsigned device) ((device & 0xffff) << 16) | (vendor & 0xffff)); } -/** default handler: only runs the relevant pci bios. */ +/** Default handler: only runs the relevant PCI BIOS. */ void pci_dev_init(struct device *dev) { #if CONFIG_PCI_ROM_RUN == 1 || CONFIG_VGA_ROM_RUN == 1 @@ -666,7 +677,7 @@ void pci_dev_init(struct device *dev) run_bios(dev, (unsigned long)ram); #if CONFIG_CONSOLE_VGA == 1 - if ((dev->class>>8) == PCI_CLASS_DISPLAY_VGA) + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) vga_console_init(); #endif /* CONFIG_CONSOLE_VGA */ #endif /* CONFIG_PCI_ROM_RUN || CONFIG_VGA_ROM_RUN */ @@ -678,13 +689,13 @@ static struct pci_operations pci_dev_ops_pci = { }; struct device_operations default_pci_ops_dev = { - .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, - .init = pci_dev_init, - .scan_bus = 0, - .enable = 0, - .ops_pci = &pci_dev_ops_pci, + .init = pci_dev_init, + .scan_bus = 0, + .enable = 0, + .ops_pci = &pci_dev_ops_pci, }; /** Default device operations for PCI bridges */ @@ -693,14 +704,14 @@ static struct pci_operations pci_bus_ops_pci = { }; struct device_operations default_pci_ops_bus = { - .read_resources = pci_bus_read_resources, - .set_resources = pci_dev_set_resources, + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, - .init = 0, - .scan_bus = pci_scan_bridge, - .enable = 0, - .reset_bus = pci_bus_reset, - .ops_pci = &pci_bus_ops_pci, + .init = 0, + .scan_bus = pci_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &pci_bus_ops_pci, }; /** @@ -711,15 +722,15 @@ struct device_operations default_pci_ops_bus = { * blocks to figure out the type of downstream bridge. PCI-X, PCI-E, and * Hypertransport all seem to have appropriate capabilities. * - * When only a PCI-Express capability is found the type - * is examined to see which type of bridge we have. + * When only a PCI-Express capability is found the type is examined to see + * which type of bridge we have. * * @param dev Pointer to the device structure of the bridge. * @return Appropriate bridge operations. */ static struct device_operations *get_pci_bridge_ops(device_t dev) { - unsigned pos; + unsigned int pos; #if CONFIG_PCIX_PLUGIN_SUPPORT == 1 pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); @@ -729,17 +740,17 @@ static struct device_operations *get_pci_bridge_ops(device_t dev) } #endif #if CONFIG_AGP_PLUGIN_SUPPORT == 1 - /* How do I detect an PCI to AGP bridge? */ + /* How do I detect a PCI to AGP bridge? */ #endif #if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1 pos = 0; while ((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) { - unsigned flags; + u16 flags; flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); if ((flags >> 13) == 1) { /* Host or Secondary Interface */ - printk(BIOS_DEBUG, "%s subordinate bus Hypertransport\n", - dev_path(dev)); + printk(BIOS_DEBUG, "%s subordinate bus HT\n", + dev_path(dev)); return &default_ht_ops_bus; } } @@ -747,17 +758,18 @@ static struct device_operations *get_pci_bridge_ops(device_t dev) #if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1 pos = pci_find_capability(dev, PCI_CAP_ID_PCIE); if (pos) { - unsigned flags; + u16 flags; flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS); switch ((flags & PCI_EXP_FLAGS_TYPE) >> 4) { case PCI_EXP_TYPE_ROOT_PORT: case PCI_EXP_TYPE_UPSTREAM: case PCI_EXP_TYPE_DOWNSTREAM: printk(BIOS_DEBUG, "%s subordinate bus PCI Express\n", - dev_path(dev)); + dev_path(dev)); return &default_pciexp_ops_bus; case PCI_EXP_TYPE_PCI_BRIDGE: - printk(BIOS_DEBUG, "%s subordinate PCI\n", dev_path(dev)); + printk(BIOS_DEBUG, "%s subordinate PCI\n", + dev_path(dev)); return &default_pci_ops_bus; default: break; @@ -779,11 +791,12 @@ static struct device_operations *get_pci_bridge_ops(device_t dev) static void set_pci_ops(struct device *dev) { struct pci_driver *driver; - if (dev->ops) { + + if (dev->ops) return; - } - /* Look through the list of setup drivers and find one for + /* + * Look through the list of setup drivers and find one for * this PCI device. */ for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) { @@ -791,16 +804,15 @@ static void set_pci_ops(struct device *dev) (driver->device == dev->device)) { dev->ops = (struct device_operations *)driver->ops; printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n", - dev_path(dev), - driver->vendor, driver->device, - (driver->ops->scan_bus ? "bus " : "")); + dev_path(dev), driver->vendor, driver->device, + (driver->ops->scan_bus ? "bus " : "")); return; } } - /* If I don't have a specific driver use the default operations */ - switch (dev->hdr_type & 0x7f) { /* header type */ - case PCI_HEADER_TYPE_NORMAL: /* standard header */ + /* If I don't have a specific driver use the default operations. */ + switch (dev->hdr_type & 0x7f) { /* Header type */ + case PCI_HEADER_TYPE_NORMAL: if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) goto bad; dev->ops = &default_pci_ops_dev; @@ -815,17 +827,15 @@ static void set_pci_ops(struct device *dev) dev->ops = &default_cardbus_ops_bus; break; #endif - default: - bad: +default: +bad: if (dev->enabled) { - printk(BIOS_ERR, "%s [%04x/%04x/%06x] has unknown header " - "type %02x, ignoring.\n", - dev_path(dev), - dev->vendor, dev->device, - dev->class >> 8, dev->hdr_type); + printk(BIOS_ERR, "%s [%04x/%04x/%06x] has unknown " + "header type %02x, ignoring.\n", dev_path(dev), + dev->vendor, dev->device, + dev->class >> 8, dev->hdr_type); } } - return; } /** @@ -843,11 +853,12 @@ static void set_pci_ops(struct device *dev) static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) { struct device *dev; + dev = 0; for (; *list; list = &(*list)->sibling) { if ((*list)->path.type != DEVICE_PATH_PCI) { - printk(BIOS_ERR, "child %s not a pci device\n", - dev_path(*list)); + printk(BIOS_ERR, "child %s not a PCI device\n", + dev_path(*list)); continue; } if ((*list)->path.pci.devfn == devfn) { @@ -859,23 +870,24 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) } } - /* Just like alloc_dev() add the device to the list of devices on the + /* + * Just like alloc_dev() add the device to the list of devices on the * bus. When the list of devices was formed we removed all of the * parents children, and now we are interleaving static and dynamic * devices in order on the bus. */ if (dev) { struct device *child; + /* Find the last child of our parent. */ - for (child = dev->bus->children; child && child->sibling;) { + for (child = dev->bus->children; child && child->sibling;) child = child->sibling; - } + /* Place the device on the list of children of its parent. */ - if (child) { + if (child) child->sibling = dev; - } else { + else dev->bus->children = dev; - } } return dev; @@ -900,25 +912,29 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) /* Detect if a device is present. */ if (!dev) { struct device dummy; + dummy.bus = bus; dummy.path.type = DEVICE_PATH_PCI; dummy.path.pci.devfn = devfn; + id = pci_read_config32(&dummy, PCI_VENDOR_ID); - /* Have we found something? - * Some broken boards return 0 if a slot is empty, but - * the expected answer is 0xffffffff + /* + * Have we found something? Some broken boards return 0 if a + * slot is empty, but the expected answer is 0xffffffff. */ - if (id == 0xffffffff) { + if (id == 0xffffffff) return NULL; - } + if ((id == 0x00000000) || (id == 0x0000ffff) || (id == 0xffff0000)) { - printk(BIOS_SPEW, "%s, bad id 0x%x\n", dev_path(&dummy), id); + printk(BIOS_SPEW, "%s, bad id 0x%x\n", + dev_path(&dummy), id); return NULL; } dev = alloc_dev(bus, &dummy.path); } else { - /* Enable/disable the device. Once we have found the device- + /* + * Enable/disable the device. Once we have found the device- * specific operations this operations we will disable the * device with those as well. * @@ -929,13 +945,14 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) * it may be absent and enable_dev() must cope. */ /* Run the magic enable sequence for the device. */ - if (dev->chip_ops && dev->chip_ops->enable_dev) { + if (dev->chip_ops && dev->chip_ops->enable_dev) dev->chip_ops->enable_dev(dev); - } + /* Now read the vendor and device ID. */ id = pci_read_config32(dev, PCI_VENDOR_ID); - /* If the device does not have a PCI ID disable it. Possibly + /* + * If the device does not have a PCI ID disable it. Possibly * this is because we have already disabled the device. But * this also handles optional devices that may not always * show up. @@ -944,13 +961,14 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) if ((id == 0xffffffff) || (id == 0x00000000) || (id == 0x0000ffff) || (id == 0xffff0000)) { if (dev->enabled) { - printk(BIOS_INFO, "PCI: Static device %s not found, disabling it.\n", - dev_path(dev)); + printk(BIOS_INFO, "PCI: Static device %s not " + "found, disabling it.\n", dev_path(dev)); dev->enabled = 0; } return dev; } } + /* Read the rest of the PCI configuration information. */ hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); class = pci_read_config32(dev, PCI_CLASS_REVISION); @@ -964,26 +982,24 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) dev->class = class >> 8; /* Architectural/System devices always need to be bus masters. */ - if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) { + if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) dev->command |= PCI_COMMAND_MASTER; - } - /* Look at the vendor and device ID, or at least the header type and + + /* + * Look at the vendor and device ID, or at least the header type and * class and figure out which set of configuration methods to use. * Unless we already have some PCI ops. */ set_pci_ops(dev); /* Now run the magic enable/disable sequence for the device. */ - if (dev->ops && dev->ops->enable) { + if (dev->ops && dev->ops->enable) dev->ops->enable(dev); - } /* Display the device. */ - printk(BIOS_DEBUG, "%s [%04x/%04x] %s%s\n", - dev_path(dev), - dev->vendor, dev->device, - dev->enabled ? "enabled" : "disabled", - dev->ops ? "" : " No operations"); + printk(BIOS_DEBUG, "%s [%04x/%04x] %s%s\n", dev_path(dev), + dev->vendor, dev->device, dev->enabled ? "enabled" : "disabled", + dev->ops ? "" : " No operations"); return dev; } @@ -1003,9 +1019,8 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) * @param max Current bus number. * @return The maximum bus number found, after scanning all subordinate busses. */ -unsigned int pci_scan_bus(struct bus *bus, - unsigned min_devfn, unsigned max_devfn, - unsigned int max) +unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, + unsigned max_devfn, unsigned int max) { unsigned int devfn; struct device *old_devices; @@ -1013,16 +1028,17 @@ unsigned int pci_scan_bus(struct bus *bus, #if CONFIG_PCI_BUS_SEGN_BITS printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %04x:%02x\n", - bus->secondary >> 8, bus->secondary & 0xff); + bus->secondary >> 8, bus->secondary & 0xff); #else printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %02x\n", bus->secondary); #endif - // Maximum sane devfn is 0xFF + /* Maximum sane devfn is 0xFF. */ if (max_devfn > 0xff) { - printk(BIOS_ERR, "PCI: pci_scan_bus limits devfn %x - devfn %x\n", - min_devfn, max_devfn ); - printk(BIOS_ERR, "PCI: pci_scan_bus upper limit too big. Using 0xff.\n"); + printk(BIOS_ERR, "PCI: pci_scan_bus limits devfn %x - " + "devfn %x\n", min_devfn, max_devfn); + printk(BIOS_ERR, "PCI: pci_scan_bus upper limit too big. " + "Using 0xff.\n"); max_devfn=0xff; } @@ -1030,50 +1046,55 @@ unsigned int pci_scan_bus(struct bus *bus, bus->children = NULL; post_code(0x24); - /* Probe all devices/functions on this bus with some optimization for + + /* + * Probe all devices/functions on this bus with some optimization for * non-existence and single function devices. */ for (devfn = min_devfn; devfn <= max_devfn; devfn++) { struct device *dev; - /* First thing setup the device structure */ + /* First thing setup the device structure. */ dev = pci_scan_get_dev(&old_devices, devfn); /* See if a device is present and setup the device structure. */ dev = pci_probe_dev(dev, bus, devfn); - /* If this is not a multi function device, or the device is + /* + * If this is not a multi function device, or the device is * not present don't waste time probing another function. * Skip to next device. */ - if ((PCI_FUNC(devfn) == 0x00) && - (!dev + if ((PCI_FUNC(devfn) == 0x00) && (!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80)))) { devfn += 0x07; } } + post_code(0x25); - /* Warn if any leftover static devices are are found. - * There's probably a problem in the Config.lb. + /* + * Warn if any leftover static devices are are found. + * There's probably a problem in devicetree.cb. */ if (old_devices) { device_t left; printk(BIOS_WARNING, "PCI: Left over static devices:\n"); - for (left = old_devices; left; left = left->sibling) { + for (left = old_devices; left; left = left->sibling) printk(BIOS_WARNING, "%s\n", dev_path(left)); - } - printk(BIOS_WARNING, "PCI: Check your mainboard Config.lb.\n"); + + printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n"); } - /* For all children that implement scan_bus() (i.e. bridges) + /* + * For all children that implement scan_bus() (i.e. bridges) * scan the bus behind that child. */ - for (child = bus->children; child; child = child->sibling) { + for (child = bus->children; child; child = child->sibling) max = scan_bus(child, max); - } - /* We've scanned the bus and so we know all about what's on the other + /* + * We've scanned the bus and so we know all about what's on the other * side of any bridges that may be on this bus plus any devices. * Return how far we've got finding sub-buses. */ @@ -1119,7 +1140,8 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max, bus = dev->link_list; - /* Set up the primary, secondary and subordinate bus numbers. We have + /* + * 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 * subordinate bus number to 0xff for the moment. */ @@ -1131,12 +1153,14 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max, pci_write_config16(dev, PCI_COMMAND, 0x0000); pci_write_config16(dev, PCI_STATUS, 0xffff); - /* Read the existing primary/secondary/subordinate bus + /* + * Read the existing primary/secondary/subordinate bus * number configuration. */ buses = pci_read_config32(dev, PCI_PRIMARY_BUS); - /* Configure the bus numbers for this bridge: the configuration + /* + * Configure the bus numbers for this bridge: the configuration * transactions will not be propagated by the bridge if it is not * correctly configured. */ @@ -1146,12 +1170,11 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max, ((unsigned int)(bus->subordinate) << 16)); pci_write_config32(dev, PCI_PRIMARY_BUS, buses); - /* Now we can scan all subordinate buses - * i.e. the bus behind the bridge. - */ + /* Now we can scan all subordinate buses (those behind the bridge). */ max = do_scan_bus(bus, 0x00, 0xff, max); - /* We know the number of buses behind this bridge. Set the subordinate + /* + * We know the number of buses behind this bridge. Set the subordinate * bus number to its real value. */ bus->subordinate = max; @@ -1200,7 +1223,7 @@ unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) * Assign IRQ numbers. * * This function assigns IRQs for all functions contained within the indicated - * device address. If the device does not exist or does not require interrupts + * device address. If the device does not exist or does not require interrupts * then this function has no effect. * * This function should be called for each PCI slot in your system. @@ -1212,14 +1235,13 @@ unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) * routing inside your southbridge and on your board. */ void pci_assign_irqs(unsigned bus, unsigned slot, - const unsigned char pIntAtoD[4]) + const unsigned char pIntAtoD[4]) { unsigned int funct; device_t pdev; - u8 line; - u8 irq; + u8 line, irq; - /* Each slot may contain up to eight functions */ + /* Each slot may contain up to eight functions. */ for (funct = 0; funct < 8; funct++) { pdev = dev_find_slot(bus, (slot << 3) + funct); @@ -1228,26 +1250,26 @@ void pci_assign_irqs(unsigned bus, unsigned slot, line = pci_read_config8(pdev, PCI_INTERRUPT_PIN); - // PCI spec says all values except 1..4 are reserved. + /* PCI spec says all values except 1..4 are reserved. */ if ((line < 1) || (line > 4)) continue; irq = pIntAtoD[line - 1]; printk(BIOS_DEBUG, "Assigning IRQ %d to %d:%x.%d\n", - irq, bus, slot, funct); + irq, bus, slot, funct); pci_write_config8(pdev, PCI_INTERRUPT_LINE, - pIntAtoD[line - 1]); + pIntAtoD[line - 1]); #ifdef PARANOID_IRQ_ASSIGNMENTS irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE); printk(BIOS_DEBUG, " Readback = %d\n", irq); #endif - // Change to level triggered - i8259_configure_irq_trigger(pIntAtoD[line - 1], IRQ_LEVEL_TRIGGERED); + /* Change to level triggered. */ + i8259_configure_irq_trigger(pIntAtoD[line - 1], + IRQ_LEVEL_TRIGGERED); } } #endif - diff --git a/src/devices/pci_ops.c b/src/devices/pci_ops.c index c3237dbdbf..07da30034f 100644 --- a/src/devices/pci_ops.c +++ b/src/devices/pci_ops.c @@ -38,93 +38,112 @@ static struct bus *get_pbus(device_t dev) else pbus = dev->bus; - while(pbus && pbus->dev && !ops_pci_bus(pbus)) { + while (pbus && pbus->dev && !ops_pci_bus(pbus)) { if (pbus == pbus->dev->bus) { - printk(BIOS_ALERT, "%s in endless loop looking for a parent " - "bus with ops_pci_bus for %s, breaking out.\n", - __func__, dev_path(dev)); + printk(BIOS_ALERT, "%s in endless loop looking for a " + "parent bus with ops_pci_bus for %s, breaking " + "out.\n", __func__, dev_path(dev)); break; } pbus = pbus->dev->bus; } - if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_pci_bus) { - /* This can happen before the device tree is set up completely. */ - //printk(BIOS_EMERG, "%s: Cannot find pci bus operations.\n", dev_path(dev)); + + if (!pbus || !pbus->dev || !pbus->dev->ops + || !pbus->dev->ops->ops_pci_bus) { + /* This can happen before the device tree is fully set up. */ + + // printk(BIOS_EMERG, "%s: Cannot find PCI bus operations.\n", + // dev_path(dev)); + pbus = NULL; } + return pbus; } -uint8_t pci_read_config8(device_t dev, unsigned where) +u8 pci_read_config8(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint16_t pci_read_config16(device_t dev, unsigned where) +u16 pci_read_config16(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint32_t pci_read_config32(device_t dev, unsigned where) +u32 pci_read_config32(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -void pci_write_config8(device_t dev, unsigned where, uint8_t val) +void pci_write_config8(device_t dev, unsigned int where, u8 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } -void pci_write_config16(device_t dev, unsigned where, uint16_t val) +void pci_write_config16(device_t dev, unsigned int where, u16 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } -void pci_write_config32(device_t dev, unsigned where, uint32_t val) +void pci_write_config32(device_t dev, unsigned int where, u32 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } #if CONFIG_MMCONF_SUPPORT -uint8_t pci_mmio_read_config8(device_t dev, unsigned where) +u8 pci_mmio_read_config8(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return pci_ops_mmconf.read8(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return pci_ops_mmconf.read8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint16_t pci_mmio_read_config16(device_t dev, unsigned where) +u16 pci_mmio_read_config16(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return pci_ops_mmconf.read16(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return pci_ops_mmconf.read16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint32_t pci_mmio_read_config32(device_t dev, unsigned where) +u32 pci_mmio_read_config32(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return pci_ops_mmconf.read32(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return pci_ops_mmconf.read32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t val) +void pci_mmio_write_config8(device_t dev, unsigned int where, u8 val) { struct bus *pbus = get_pbus(dev); - pci_ops_mmconf.write8(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + pci_ops_mmconf.write8(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); } -void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t val) +void pci_mmio_write_config16(device_t dev, unsigned int where, u16 val) { struct bus *pbus = get_pbus(dev); - pci_ops_mmconf.write16(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + pci_ops_mmconf.write16(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); } -void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t val) +void pci_mmio_write_config32(device_t dev, unsigned int where, u32 val) { struct bus *pbus = get_pbus(dev); - pci_ops_mmconf.write32(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + pci_ops_mmconf.write32(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); } + #endif diff --git a/src/devices/pci_rom.c b/src/devices/pci_rom.c index 50351b43dc..1ae79e137d 100644 --- a/src/devices/pci_rom.c +++ b/src/devices/pci_rom.c @@ -38,59 +38,62 @@ struct rom_header *pci_rom_probe(struct device *dev) rom_header = cbfs_load_optionrom(dev->vendor, dev->device, NULL); if (rom_header) { - printk(BIOS_DEBUG, "In cbfs, rom address for %s = %p\n", - dev_path(dev), rom_header); + printk(BIOS_DEBUG, "In CBFS, ROM address for %s = %p\n", + dev_path(dev), rom_header); } else { - unsigned long rom_address; + u32 rom_address; rom_address = pci_read_config32(dev, PCI_ROM_ADDRESS); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { - #if defined(CONFIG_BOARD_EMULATION_QEMU_X86) \ - && CONFIG_BOARD_EMULATION_QEMU_X86 +#if defined(CONFIG_BOARD_EMULATION_QEMU_X86) && CONFIG_BOARD_EMULATION_QEMU_X86 if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) rom_address = 0xc0000; else - #endif +#endif return NULL; } else { - /* enable expansion ROM address decoding */ + /* Enable expansion ROM address decoding. */ pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address|PCI_ROM_ADDRESS_ENABLE); } - printk(BIOS_DEBUG, "On card, rom address for %s = %lx\n", - dev_path(dev), rom_address); + printk(BIOS_DEBUG, "On card, ROM address for %s = %lx\n", + dev_path(dev), (unsigned long)rom_address); rom_header = (struct rom_header *)rom_address; } - printk(BIOS_SPEW, "PCI Expansion ROM, signature 0x%04x, INIT size 0x%04x, data ptr 0x%04x\n", - le32_to_cpu(rom_header->signature), - rom_header->size * 512, le32_to_cpu(rom_header->data)); + printk(BIOS_SPEW, "PCI expansion ROM, signature 0x%04x, " + "INIT size 0x%04x, data ptr 0x%04x\n", + le32_to_cpu(rom_header->signature), + rom_header->size * 512, le32_to_cpu(rom_header->data)); + if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { - printk(BIOS_ERR, "Incorrect Expansion ROM Header Signature %04x\n", - le32_to_cpu(rom_header->signature)); + printk(BIOS_ERR, "Incorrect expansion ROM header " + "signature %04x\n", le32_to_cpu(rom_header->signature)); return NULL; } rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data)); - printk(BIOS_SPEW, "PCI ROM Image, Vendor %04x, Device %04x,\n", - rom_data->vendor, rom_data->device); - if (dev->vendor != rom_data->vendor || dev->device != rom_data->device) { - printk(BIOS_ERR, "ID mismatch: Vendor ID %04x, Device ID %04x\n", - rom_data->vendor, rom_data->device); + printk(BIOS_SPEW, "PCI ROM image, vendor ID %04x, device ID %04x,\n", + rom_data->vendor, rom_data->device); + if (dev->vendor != rom_data->vendor + || dev->device != rom_data->device) { + printk(BIOS_ERR, "ID mismatch: vendor ID %04x, " + "device ID %04x\n", rom_data->vendor, rom_data->device); return NULL; } - printk(BIOS_SPEW, "PCI ROM Image, Class Code %04x%02x, Code Type %02x\n", - rom_data->class_hi, rom_data->class_lo, - rom_data->type); + printk(BIOS_SPEW, "PCI ROM image, Class Code %04x%02x, " + "Code Type %02x\n", rom_data->class_hi, rom_data->class_lo, + rom_data->type); + if (dev->class != ((rom_data->class_hi << 8) | rom_data->class_lo)) { printk(BIOS_DEBUG, "Class Code mismatch ROM %08x, dev %08x\n", - (rom_data->class_hi << 8) | rom_data->class_lo, - dev->class); - //return NULL; + (rom_data->class_hi << 8) | rom_data->class_lo, + dev->class); + // return NULL; } return rom_header; @@ -98,41 +101,51 @@ struct rom_header *pci_rom_probe(struct device *dev) static void *pci_ram_image_start = (void *)PCI_RAM_IMAGE_START; -struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header) +struct rom_header *pci_rom_load(struct device *dev, + struct rom_header *rom_header) { struct pci_data * rom_data; unsigned int rom_size; unsigned int image_size=0; do { - rom_header = (struct rom_header *)((void *) rom_header + image_size); // get next image - rom_data = (struct pci_data *)((void *) rom_header + le32_to_cpu(rom_header->data)); - image_size = le32_to_cpu(rom_data->ilen) * 512; - } while ((rom_data->type!=0) && (rom_data->indicator!=0)); // make sure we got x86 version + /* Get next image. */ + rom_header = (struct rom_header *)((void *) rom_header + + image_size); + + rom_data = (struct pci_data *)((void *) rom_header + + le32_to_cpu(rom_header->data)); + + image_size = le32_to_cpu(rom_data->ilen) * 512; + } while ((rom_data->type != 0) && (rom_data->indicator != 0)); // make sure we got x86 version if (rom_data->type != 0) return NULL; rom_size = rom_header->size * 512; - // We check to see if the device thinks it is a VGA device not - // whether the ROM image is for a VGA device because some - // devices have a mismatch between the hardware and the ROM + /* + * We check to see if the device thinks it is a VGA device not + * whether the ROM image is for a VGA device because some + * devices have a mismatch between the hardware and the ROM. + */ if (PCI_CLASS_DISPLAY_VGA == (dev->class >> 8)) { #if CONFIG_CONSOLE_VGA == 1 && CONFIG_CONSOLE_VGA_MULTI == 0 - extern device_t vga_pri; // the primary vga device, defined in device.c - if (dev != vga_pri) return NULL; // only one VGA supported + extern device_t vga_pri; /* Primary VGA device (device.c). */ + if (dev != vga_pri) return NULL; /* Only one VGA supported. */ #endif if ((void *)PCI_VGA_RAM_IMAGE_START != rom_header) { - printk(BIOS_DEBUG, "copying VGA ROM Image from %p to 0x%x, 0x%x bytes\n", - rom_header, PCI_VGA_RAM_IMAGE_START, rom_size); - memcpy((void *)PCI_VGA_RAM_IMAGE_START, rom_header, rom_size); + printk(BIOS_DEBUG, "Copying VGA ROM Image from %p to " + "0x%x, 0x%x bytes\n", rom_header, + PCI_VGA_RAM_IMAGE_START, rom_size); + memcpy((void *)PCI_VGA_RAM_IMAGE_START, rom_header, + rom_size); } return (struct rom_header *) (PCI_VGA_RAM_IMAGE_START); } - printk(BIOS_DEBUG, "copying non-VGA ROM Image from %p to %p, 0x%x bytes\n", - rom_header, pci_ram_image_start, rom_size); + printk(BIOS_DEBUG, "Copying non-VGA ROM image from %p to %p, 0x%x " + "bytes\n", rom_header, pci_ram_image_start, rom_size); memcpy(pci_ram_image_start, rom_header, rom_size); pci_ram_image_start += rom_size; diff --git a/src/devices/pciexp_device.c b/src/devices/pciexp_device.c index 0349f96c0c..b190285c3b 100644 --- a/src/devices/pciexp_device.c +++ b/src/devices/pciexp_device.c @@ -27,6 +27,9 @@ static void pciexp_tune_dev(device_t dev) { unsigned int cap; +#ifdef CONFIG_PCIE_TUNING + u32 reg32; +#endif cap = pci_find_capability(dev, PCI_CAP_ID_PCIE); if (!cap) @@ -35,9 +38,9 @@ static void pciexp_tune_dev(device_t dev) #ifdef CONFIG_PCIE_TUNING printk(BIOS_DEBUG, "PCIe: tuning %s\n", dev_path(dev)); - // TODO make this depending on ASPM - /* Enable ASPM Role Based Error Reporting */ - u32 reg32; + // TODO make this depending on ASPM. + + /* Enable ASPM role based error reporting. */ reg32 = pci_read_config32(dev, cap + PCI_EXP_DEVCAP); reg32 |= PCI_EXP_DEVCAP_RBER; pci_write_config32(dev, cap + PCI_EXP_DEVCAP, reg32); diff --git a/src/devices/pcix_device.c b/src/devices/pcix_device.c index 22dd06e5bd..6bfd35dc60 100644 --- a/src/devices/pcix_device.c +++ b/src/devices/pcix_device.c @@ -56,7 +56,7 @@ static void pcix_tune_dev(device_t dev) /* Don't attempt to handle PCI-X errors. */ cmd &= ~PCI_X_CMD_DPERR_E; - /* Enable Relaxed Ordering. */ + /* Enable relaxed ordering. */ cmd |= PCI_X_CMD_ERO; if (orig_cmd != cmd) @@ -108,6 +108,7 @@ const char *pcix_speed(u16 sstatus) result = pcix_533mhz; break; } + return result; } diff --git a/src/devices/pnp_device.c b/src/devices/pnp_device.c index 702aa9253c..b2bca03232 100644 --- a/src/devices/pnp_device.c +++ b/src/devices/pnp_device.c @@ -163,7 +163,7 @@ struct device_operations pnp_ops = { .enable = pnp_enable, }; -/* PNP chip opertations */ +/* PNP chip operations */ static void pnp_get_ioresource(device_t dev, u8 index, struct io_info *info) { @@ -214,18 +214,15 @@ static void get_resources(device_t dev, struct pnp_info *info) { struct resource *resource; - if (info->flags & PNP_IO0) { + if (info->flags & PNP_IO0) pnp_get_ioresource(dev, PNP_IDX_IO0, &info->io0); - } - if (info->flags & PNP_IO1) { + if (info->flags & PNP_IO1) pnp_get_ioresource(dev, PNP_IDX_IO1, &info->io1); - } - if (info->flags & PNP_IO2) { + if (info->flags & PNP_IO2) pnp_get_ioresource(dev, PNP_IDX_IO2, &info->io2); - } - if (info->flags & PNP_IO3) { + if (info->flags & PNP_IO3) pnp_get_ioresource(dev, PNP_IDX_IO3, &info->io3); - } + if (info->flags & PNP_IRQ0) { resource = new_resource(dev, PNP_IDX_IRQ0); resource->size = 1; @@ -236,6 +233,7 @@ static void get_resources(device_t dev, struct pnp_info *info) resource->size = 1; resource->flags |= IORESOURCE_IRQ; } + if (info->flags & PNP_DRQ0) { resource = new_resource(dev, PNP_IDX_DRQ0); resource->size = 1; diff --git a/src/devices/smbus_ops.c b/src/devices/smbus_ops.c index bac73986da..75ca42b0c9 100644 --- a/src/devices/smbus_ops.c +++ b/src/devices/smbus_ops.c @@ -43,7 +43,7 @@ struct bus *get_pbus_smbus(device_t dev) } /* - * Multi-level I2C MUX? may need to find the first i2c device and then set link + * Multi-level I2C MUX? May need to find the first I2C device and then set link * down to current dev. * * 1 store get_pbus_smbus list link diff --git a/src/include/device/device.h b/src/include/device/device.h index 1b978b1540..7dbbb4f5ae 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -120,7 +120,7 @@ void run_bios(struct device *dev, unsigned long addr); /* Helper functions */ device_t find_dev_path(struct bus *parent, struct device_path *path); device_t alloc_find_dev(struct bus *parent, struct device_path *path); -device_t dev_find_device (unsigned int vendor, unsigned int device, device_t from); +device_t dev_find_device (u16 vendor, u16 device, device_t from); device_t dev_find_class (unsigned int class, device_t from); device_t dev_find_slot (unsigned int bus, unsigned int devfn); device_t dev_find_slot_on_smbus (unsigned int bus, unsigned int addr); diff --git a/src/include/device/pci.h b/src/include/device/pci.h index 131564c8c5..6af723d745 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -15,6 +15,7 @@ #ifndef PCI_H #define PCI_H +#include <stdint.h> #include <device/pci_def.h> #include <device/resource.h> #include <device/device.h> diff --git a/src/include/device/pci_ops.h b/src/include/device/pci_ops.h index 13eee9d4a9..e5e54b6d4d 100644 --- a/src/include/device/pci_ops.h +++ b/src/include/device/pci_ops.h @@ -5,20 +5,20 @@ #include <device/device.h> #include <arch/pci_ops.h> -uint8_t pci_read_config8(device_t dev, unsigned where); -uint16_t pci_read_config16(device_t dev, unsigned where); -uint32_t pci_read_config32(device_t dev, unsigned where); -void pci_write_config8(device_t dev, unsigned where, uint8_t val); -void pci_write_config16(device_t dev, unsigned where, uint16_t val); -void pci_write_config32(device_t dev, unsigned where, uint32_t val); +u8 pci_read_config8(device_t dev, unsigned int where); +u16 pci_read_config16(device_t dev, unsigned int where); +u32 pci_read_config32(device_t dev, unsigned int where); +void pci_write_config8(device_t dev, unsigned int where, u8 val); +void pci_write_config16(device_t dev, unsigned int where, u16 val); +void pci_write_config32(device_t dev, unsigned int where, u32 val); #if CONFIG_MMCONF_SUPPORT -uint8_t pci_mmio_read_config8(device_t dev, unsigned where); -uint16_t pci_mmio_read_config16(device_t dev, unsigned where); -uint32_t pci_mmio_read_config32(device_t dev, unsigned where); -void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t val); -void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t val); -void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t val); +u8 pci_mmio_read_config8(device_t dev, unsigned int where); +u16 pci_mmio_read_config16(device_t dev, unsigned int where); +u32 pci_mmio_read_config32(device_t dev, unsigned int where); +void pci_mmio_write_config8(device_t dev, unsigned int where, u8 val); +void pci_mmio_write_config16(device_t dev, unsigned int where, u16 val); +void pci_mmio_write_config32(device_t dev, unsigned int where, u32 val); #endif /* This function lives in pci_ops_auto.c */ |