summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/probe.c5
-rw-r--r--drivers/pci/setup-bus.c3
-rw-r--r--drivers/pci/setup-res.c42
3 files changed, 29 insertions, 21 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c2e99fd87faf..33d9b8bea6e0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -235,7 +235,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
}
res->end = res->start + (unsigned long) sz;
- res->flags |= pci_calc_resource_flags(l);
+ res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
if (is_64bit_memory(l)) {
u32 szhi, lhi;
@@ -288,7 +288,8 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
if (sz) {
res->flags = (l & IORESOURCE_ROM_ENABLE) |
IORESOURCE_MEM | IORESOURCE_PREFETCH |
- IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+ IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
+ IORESOURCE_SIZEALIGN;
res->start = l & PCI_ROM_ADDRESS_MASK;
res->end = res->start + (unsigned long) sz;
}
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index f7cb8e0758b4..5cf84568c9e4 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -65,6 +65,7 @@ static void pbus_assign_resources_sorted(struct pci_bus *bus)
res = list->res;
idx = res - &list->dev->resource[0];
if (pci_assign_resource(list->dev, idx)) {
+ /* FIXME: get rid of this */
res->start = 0;
res->end = 0;
res->flags = 0;
@@ -327,6 +328,7 @@ static void pbus_size_io(struct pci_bus *bus)
/* Alignment of the IO window is always 4K */
b_res->start = 4096;
b_res->end = b_res->start + size - 1;
+ b_res->flags |= IORESOURCE_STARTALIGN;
}
/* Calculate the size of the bus and minimal alignment which
@@ -401,6 +403,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
}
b_res->start = min_align;
b_res->end = size + min_align - 1;
+ b_res->flags |= IORESOURCE_STARTALIGN;
return 1;
}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index bad509e40fbc..7d35cdf4579f 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -137,10 +137,16 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
size = res->end - res->start + 1;
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
- /* The bridge resources are special, as their
- size != alignment. Sizing routines return
- required alignment in the "start" field. */
- align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;
+
+ align = resource_alignment(res);
+ if (!align) {
+ printk(KERN_ERR "PCI: Cannot allocate resource (bogus "
+ "alignment) %d [%llx:%llx] (flags %lx) of %s\n",
+ resno, (unsigned long long)res->start,
+ (unsigned long long)res->end, res->flags,
+ pci_name(dev));
+ return -EINVAL;
+ }
/* First, try exact prefetching match.. */
ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -164,8 +170,10 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
res->flags & IORESOURCE_IO ? "I/O" : "mem",
resno, (unsigned long long)size,
(unsigned long long)res->start, pci_name(dev));
- } else if (resno < PCI_BRIDGE_RESOURCES) {
- pci_update_resource(dev, res, resno);
+ } else {
+ res->flags &= ~IORESOURCE_STARTALIGN;
+ if (resno < PCI_BRIDGE_RESOURCES)
+ pci_update_resource(dev, res, resno);
}
return ret;
@@ -226,29 +234,25 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
if (r->flags & IORESOURCE_PCI_FIXED)
continue;
- r_align = r->end - r->start;
-
if (!(r->flags) || r->parent)
continue;
+
+ r_align = resource_alignment(r);
if (!r_align) {
- printk(KERN_WARNING "PCI: Ignore bogus resource %d "
- "[%llx:%llx] of %s\n",
+ printk(KERN_WARNING "PCI: bogus alignment of resource "
+ "%d [%llx:%llx] (flags %lx) of %s\n",
i, (unsigned long long)r->start,
- (unsigned long long)r->end, pci_name(dev));
+ (unsigned long long)r->end, r->flags,
+ pci_name(dev));
continue;
}
- r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
for (list = head; ; list = list->next) {
resource_size_t align = 0;
struct resource_list *ln = list->next;
- int idx;
- if (ln) {
- idx = ln->res - &ln->dev->resource[0];
- align = (idx < PCI_BRIDGE_RESOURCES) ?
- ln->res->end - ln->res->start + 1 :
- ln->res->start;
- }
+ if (ln)
+ align = resource_alignment(ln->res);
+
if (r_align > align) {
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp)