+ struct device *child;
+ struct resource *res;
+ struct resource *lim;
+ struct bus *link;
+
+ printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
+
+ /* Constrain limits based on the fixed resources of this device. */
+ for (res = dev->resource_list; res; res = res->next) {
+ if (!(res->flags & IORESOURCE_FIXED))
+ 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);
+ continue;
+ }
+
+ /* PREFETCH, MEM, or I/O - skip any others. */
+ if ((res->flags & MEM_MASK) == PREF_TYPE)
+ lim = &limits->pref;
+ else if ((res->flags & MEM_MASK) == MEM_TYPE)
+ lim = &limits->mem;
+ else if ((res->flags & IO_MASK) == IO_TYPE)
+ lim = &limits->io;
+ 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))
+ continue;
+
+ /*
+ * 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))
+ 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) {
+ if (child->enabled)
+ constrain_resources(child, limits);
+ }
+ }
+}
+
+static void avoid_fixed_resources(struct device *dev)
+{
+ struct constraints limits;
+ struct resource *res;
+
+ printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
+
+ /* Initialize constraints to maximum size. */
+ limits.pref.base = 0;
+ limits.pref.limit = 0xffffffffffffffffULL;
+ limits.io.base = 0;
+ limits.io.limit = 0xffffffffffffffffULL;
+ limits.mem.base = 0;
+ limits.mem.limit = 0xffffffffffffffffULL;
+
+ /* Constrain the limits to dev's initial resources. */
+ for (res = dev->resource_list; res; res = res->next) {
+ if ((res->flags & IORESOURCE_FIXED))
+ continue;
+ printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
+ dev_path(dev), res->index, res->limit);
+ if ((res->flags & MEM_MASK) == PREF_TYPE &&
+ (res->limit < limits.pref.limit))
+ limits.pref.limit = res->limit;
+ if ((res->flags & MEM_MASK) == MEM_TYPE &&
+ (res->limit < limits.mem.limit))
+ limits.mem.limit = res->limit;
+ if ((res->flags & IO_MASK) == IO_TYPE &&
+ (res->limit < limits.io.limit))
+ limits.io.limit = res->limit;
+ }
+
+ /* Look through the tree for fixed resources and update the limits. */
+ constrain_resources(dev, &limits);
+
+ /* Update dev's resources with new limits. */
+ for (res = dev->resource_list; res; res = res->next) {
+ struct resource *lim;
+
+ if ((res->flags & IORESOURCE_FIXED))
+ continue;
+
+ /* PREFETCH, MEM, or I/O - skip any others. */
+ if ((res->flags & MEM_MASK) == PREF_TYPE)
+ lim = &limits.pref;
+ else if ((res->flags & MEM_MASK) == MEM_TYPE)
+ lim = &limits.mem;
+ else if ((res->flags & IO_MASK) == IO_TYPE)
+ lim = &limits.io;
+ else
+ continue;
+
+ printk(BIOS_SPEW, "%s2: %s@%02lx limit %08llx\n", __func__,
+ dev_path(dev), res->index, res->limit);
+ printk(BIOS_SPEW, "\tlim->base %08llx lim->limit %08llx\n",
+ lim->base, lim->limit);
+
+ /* Is the resource outside the limits? */
+ if (lim->base > res->base)
+ res->base = lim->base;
+ if (res->limit > lim->limit)
+ res->limit = lim->limit;
+ }
+}
+
+#if CONFIG_VGA_BRIDGE_SETUP == 1
+device_t vga_pri = 0;
+static void set_vga_bridge_bits(void)
+{
+ /*
+ * 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.
+ */
+
+ /* 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)
+ vga_onboard = dev;
+ else
+ vga_first = dev;