PCI: clean up resource alignment management
[linux-2.6.git] / drivers / pci / setup-res.c
index bad509e..7d35cdf 100644 (file)
@@ -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)