Commit 5d0a8965 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Linus Torvalds

[PATCH] 2.5.14: New PCI allocation code (alpha, arm, parisc) [2/2]

Summary of changes:
- alpha, arm: code related to PCI-PCI bridges from pcibios_fixup_bus()
  removed - now it's generic;
- pdev_sort_resource: sort resources all together, no matter IO or memory;
- pbus_assign_resources_sorted: ditto;
- pci_bridge_check_ranges, pci_setup_bridge: changed for prefetch support;
- pbus_size_io, pbus_size_mem: core stuff; tested with randomly generated
  sets of resources;
- pbus_size_bridges: pass #2 (pass #1 is PCI probing, common for all archs);
- pbus_assign_resources: pass #3.

Ivan.
parent 8a3d0b80
...@@ -246,25 +246,6 @@ pcibios_fixup_bus(struct pci_bus *bus) ...@@ -246,25 +246,6 @@ pcibios_fixup_bus(struct pci_bus *bus)
/* Root bus */ /* Root bus */
bus->resource[0] = hose->io_space; bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space; bus->resource[1] = hose->mem_space;
} else {
/* This is a bridge. Do not care how it's initialized,
just link its resources to the bus ones */
int i;
for(i=0; i<3; i++) {
bus->resource[i] =
&dev->resource[PCI_BRIDGE_RESOURCES+i];
bus->resource[i]->name = bus->name;
}
bus->resource[0]->flags |= pci_bridge_check_io(dev);
bus->resource[1]->flags |= IORESOURCE_MEM;
/* For now, propogate hose limits to the bus;
we'll adjust them later. */
bus->resource[0]->end = hose->io_space->end;
bus->resource[1]->end = hose->mem_space->end;
/* Turn off downstream PF memory address range by default */
bus->resource[2]->start = 1024*1024;
bus->resource[2]->end = bus->resource[2]->start - 1;
} }
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
...@@ -349,6 +330,10 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus, ...@@ -349,6 +330,10 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus,
ranges->io_end -= hose->io_space->start; ranges->io_end -= hose->io_space->start;
ranges->mem_start -= hose->mem_space->start; ranges->mem_start -= hose->mem_space->start;
ranges->mem_end -= hose->mem_space->start; ranges->mem_end -= hose->mem_space->start;
/* FIXME: On older alphas we could use dense memory space
to access prefetchable resources. */
ranges->prefetch_start -= hose->mem_space->start;
ranges->prefetch_end -= hose->mem_space->start;
} }
int int
......
...@@ -346,20 +346,7 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root) ...@@ -346,20 +346,7 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
struct pci_dev *dev = bus->self; struct pci_dev *dev = bus->self;
int i; int i;
if (dev) { if (!dev) {
for (i = 0; i < 3; i++) {
if (root->resource[i]) {
bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
bus->resource[i]->end = root->resource[i]->end;
bus->resource[i]->name = bus->name;
}
}
bus->resource[0]->flags |= pci_bridge_check_io(dev);
bus->resource[1]->flags |= IORESOURCE_MEM;
if (bus->resource[2] && root->resource[2])
bus->resource[2]->flags = root->resource[2]->flags;
} else {
/* /*
* Assign root bus resources. * Assign root bus resources.
*/ */
......
This diff is collapsed.
...@@ -136,47 +136,45 @@ pci_assign_resource(struct pci_dev *dev, int i) ...@@ -136,47 +136,45 @@ pci_assign_resource(struct pci_dev *dev, int i)
return 0; return 0;
} }
/* Sort resources of a given type by alignment */ /* Sort resources by alignment */
void __init void __init
pdev_sort_resources(struct pci_dev *dev, pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
struct resource_list *head, u32 type_mask)
{ {
int i; int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) { for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r; struct resource *r;
struct resource_list *list, *tmp; struct resource_list *list, *tmp;
unsigned long r_size; unsigned long r_align;
/* PCI-PCI bridges may have I/O ports or
memory on the primary bus */
if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
i >= PCI_BRIDGE_RESOURCES)
continue;
r = &dev->resource[i]; r = &dev->resource[i];
r_size = r->end - r->start; r_align = r->end - r->start;
if (!(r->flags & type_mask) || r->parent) if (!(r->flags) || r->parent)
continue; continue;
if (!r_size) { if (!r_align) {
printk(KERN_WARNING "PCI: Ignore bogus resource %d " printk(KERN_WARNING "PCI: Ignore bogus resource %d "
"[%lx:%lx] of %s\n", "[%lx:%lx] of %s\n",
i, r->start, r->end, dev->name); i, r->start, r->end, dev->name);
continue; continue;
} }
r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
for (list = head; ; list = list->next) { for (list = head; ; list = list->next) {
unsigned long size = 0; unsigned long align = 0;
struct resource_list *ln = list->next; struct resource_list *ln = list->next;
int idx;
if (ln) if (ln) {
size = ln->res->end - ln->res->start; idx = ln->res - &ln->dev->resource[0];
if (r_size > size) { align = (idx < PCI_BRIDGE_RESOURCES) ?
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); ln->res->end - ln->res->start + 1 :
if (!tmp) { ln->res->start;
printk(KERN_ERR "pdev_sort_resources(): kmalloc() failed!\n");
continue;
} }
if (r_align > align) {
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp)
panic("pdev_sort_resources(): "
"kmalloc() failed!\n");
tmp->next = ln; tmp->next = ln;
tmp->res = r; tmp->res = r;
tmp->dev = dev; tmp->dev = dev;
......
...@@ -464,9 +464,9 @@ struct pci_ops { ...@@ -464,9 +464,9 @@ struct pci_ops {
struct pbus_set_ranges_data struct pbus_set_ranges_data
{ {
int found_vga;
unsigned long io_start, io_end; unsigned long io_start, io_end;
unsigned long mem_start, mem_end; unsigned long mem_start, mem_end;
unsigned long prefetch_start, prefetch_end;
}; };
struct pci_device_id { struct pci_device_id {
...@@ -582,8 +582,7 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable); ...@@ -582,8 +582,7 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
int pci_claim_resource(struct pci_dev *, int); int pci_claim_resource(struct pci_dev *, int);
void pci_assign_unassigned_resources(void); void pci_assign_unassigned_resources(void);
void pdev_enable_device(struct pci_dev *); void pdev_enable_device(struct pci_dev *);
void pdev_sort_resources(struct pci_dev *, struct resource_list *, u32); void pdev_sort_resources(struct pci_dev *, struct resource_list *);
unsigned long pci_bridge_check_io(struct pci_dev *);
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
int (*)(struct pci_dev *, u8, u8)); int (*)(struct pci_dev *, u8, u8));
#define HAVE_PCI_REQ_REGIONS #define HAVE_PCI_REQ_REGIONS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment