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

From: Ivan Kokshaysky (ink@jurassic.park.msu.ru)
Date: Tue May 07 2002 - 10:49:32 EST


This changes PCI resource allocation algorithm to 3 passes vs.
current 2 passes. Extra pass is used for calculation of required
size and alignment of PCI buses behind PCI-PCI bridges. After
that, in the pass #3, these buses get allocated like regular
PCI devices. This gives tighter PCI IO and memory packing -
for instance, this fixes allocation problems on certain alphas
with very small (112Mb) PCI memory range. Also, the new code
- will allow mixed approach to resource allocation:
  architecture can keep BIOS settings for some devices,
  and re-allocate resources for others, including improperly
  initialized bridges;
- makes prefetchable ranges support much simpler;
- allows sizing of IO and memory ranges for the host
  bridges, which might be very useful in some situations.

It was tested on various alphas; I haven't heard any complaints
from rmk and rth, so probably all of this is ok. :-)

Part 1:
- for all archs, 4th argument (align) added to
  pcibios_align_resource (and its callers).
  It's necessary because this function will be called for
  bus resources as well, and in this case size != alignment.
- for several archs, dead/bogus code removed from
  pcibios_fixup_pbus_ranges().

Ivan.

--- 2.5.14/arch/i386/kernel/pci-i386.c Fri May 3 04:22:45 2002
+++ linux/arch/i386/kernel/pci-i386.c Sun May 5 18:40:21 2002
@@ -136,7 +136,8 @@ pcibios_update_resource(struct pci_dev *
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         if (res->flags & IORESOURCE_IO) {
                 unsigned long start = res->start;
--- 2.5.14/arch/sparc64/kernel/pci.c Fri May 3 04:22:37 2002
+++ linux/arch/sparc64/kernel/pci.c Sun May 5 18:40:21 2002
@@ -311,7 +311,8 @@ void pcibios_fixup_pbus_ranges(struct pc
 {
 }
 
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/ppc/kernel/pci.c Fri May 3 04:22:52 2002
+++ linux/arch/ppc/kernel/pci.c Sun May 5 18:40:21 2002
@@ -1083,10 +1083,6 @@ common_swizzle(struct pci_dev *dev, unsi
 void __init
 pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
--- 2.5.14/arch/mips/kernel/pci.c Fri May 3 04:22:43 2002
+++ linux/arch/mips/kernel/pci.c Sun May 5 18:40:21 2002
@@ -161,7 +161,8 @@ char *pcibios_setup(char *str)
 }
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         /* this should not be called */
 }
--- 2.5.14/arch/mips/ite-boards/generic/it8172_pci.c Fri May 3 04:22:55 2002
+++ linux/arch/mips/ite-boards/generic/it8172_pci.c Sun May 5 18:40:21 2002
@@ -241,7 +241,8 @@ pcibios_enable_device(struct pci_dev *de
 
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
     printk("pcibios_align_resource\n");
 }
--- 2.5.14/arch/mips/mips-boards/generic/pci.c Fri May 3 04:22:50 2002
+++ linux/arch/mips/mips-boards/generic/pci.c Mon May 6 21:28:07 2002
@@ -286,7 +286,8 @@ pcibios_enable_device(struct pci_dev *de
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/mips/ddb5xxx/common/pci.c Fri May 3 04:22:57 2002
+++ linux/arch/mips/ddb5xxx/common/pci.c Sun May 5 18:40:21 2002
@@ -164,7 +164,8 @@ char *pcibios_setup(char *str)
 }
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         /* this should not be called */
         MIPS_ASSERT(1 == 0);
--- 2.5.14/arch/mips/gt64120/common/pci.c Fri May 3 04:22:53 2002
+++ linux/arch/mips/gt64120/common/pci.c Mon May 6 21:27:03 2002
@@ -886,7 +886,7 @@ void pcibios_update_resource(struct pci_
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
- unsigned long size)
+ unsigned long size, unsigned long align)
 {
         struct pci_dev *dev = data;
 
--- 2.5.14/arch/mips/ddb5074/pci.c Fri May 3 04:22:53 2002
+++ linux/arch/mips/ddb5074/pci.c Sun May 5 18:40:21 2002
@@ -319,10 +319,6 @@ void __init pcibios_update_irq(struct pc
 void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
                                       struct pbus_set_ranges_data *ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 int pcibios_enable_resources(struct pci_dev *dev)
@@ -396,7 +392,7 @@ void pcibios_update_resource(struct pci_
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
- unsigned long size)
+ unsigned long size, unsigned long align)
 {
         struct pci_dev *dev = data;
 
--- 2.5.14/arch/mips/ddb5476/pci.c Fri May 3 04:22:49 2002
+++ linux/arch/mips/ddb5476/pci.c Sun May 5 18:40:21 2002
@@ -470,7 +470,7 @@ void pcibios_update_resource(struct pci_
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
- unsigned long size)
+ unsigned long size, unsigned long align)
 {
         struct pci_dev *dev = data;
 
--- 2.5.14/arch/mips/sni/pci.c Fri May 3 04:22:54 2002
+++ linux/arch/mips/sni/pci.c Sun May 5 18:40:21 2002
@@ -199,7 +199,8 @@ int __init pcibios_enable_device(struct
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/alpha/kernel/pci.c Fri May 3 04:22:40 2002
+++ linux/arch/alpha/kernel/pci.c Mon May 6 21:34:29 2002
@@ -128,7 +128,8 @@ struct pci_fixup pcibios_fixups[] __init
 #define GB (1024*MB)
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         struct pci_dev *dev = data;
         struct pci_controller *hose = dev->sysdata;
@@ -168,7 +169,7 @@ pcibios_align_resource(void *data, struc
                  */
 
                 /* Align to multiple of size of minimum base. */
- alignto = MAX(0x1000, size);
+ alignto = MAX(0x1000, align);
                 start = ALIGN(start, alignto);
                 if (hose->sparse_mem_base && size <= 7 * 16*MB) {
                         if (((start / (16*MB)) & 0x7) == 0) {
--- 2.5.14/arch/sparc/kernel/pcic.c Fri May 3 04:22:37 2002
+++ linux/arch/sparc/kernel/pcic.c Mon May 6 21:26:04 2002
@@ -865,7 +865,8 @@ void pcibios_update_resource(struct pci_
 {
 }
 
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/x86_64/kernel/pci-x86_64.c Fri May 3 04:22:57 2002
+++ linux/arch/x86_64/kernel/pci-x86_64.c Sun May 5 18:40:21 2002
@@ -136,7 +136,8 @@ pcibios_update_resource(struct pci_dev *
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         if (res->flags & IORESOURCE_IO) {
                 unsigned long start = res->start;
--- 2.5.14/arch/ia64/kernel/pci.c Fri May 3 04:22:52 2002
+++ linux/arch/ia64/kernel/pci.c Sun May 5 18:40:21 2002
@@ -259,10 +259,6 @@ pcibios_update_irq (struct pci_dev *dev,
 void __init
 pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 int
@@ -278,7 +274,8 @@ pcibios_enable_device (struct pci_dev *d
 }
 
 void
-pcibios_align_resource (void *data, struct resource *res, unsigned long size)
+pcibios_align_resource (void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/arm/kernel/bios32.c Fri May 3 04:22:50 2002
+++ linux/arch/arm/kernel/bios32.c Mon May 6 21:34:29 2002
@@ -662,7 +662,8 @@ char * __init pcibios_setup(char *str)
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         if (res->flags & IORESOURCE_IO) {
                 unsigned long start = res->start;
--- 2.5.14/arch/mips64/sgi-ip27/ip27-pci.c Fri May 3 04:22:55 2002
+++ linux/arch/mips64/sgi-ip27/ip27-pci.c Sun May 5 18:40:21 2002
@@ -238,10 +238,6 @@ void __init
 pcibios_fixup_pbus_ranges(struct pci_bus * bus,
                           struct pbus_set_ranges_data * ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 int __init
@@ -252,7 +248,8 @@ pcibios_enable_device(struct pci_dev *de
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/mips64/mips-boards/generic/pci.c Fri May 3 04:22:41 2002
+++ linux/arch/mips64/mips-boards/generic/pci.c Sun May 5 18:40:21 2002
@@ -290,7 +290,8 @@ pcibios_enable_device(struct pci_dev *de
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
 }
 
--- 2.5.14/arch/mips64/sgi-ip32/ip32-pci.c Fri May 3 04:22:58 2002
+++ linux/arch/mips64/sgi-ip32/ip32-pci.c Sun May 5 18:40:21 2002
@@ -329,7 +329,7 @@ char * __init pcibios_setup (char *str)
 }
 
 void __init pcibios_align_resource (void *data, struct resource *res,
- unsigned long size)
+ unsigned long size, unsigned long align)
 {
 }
 
@@ -352,10 +352,6 @@ void __init pcibios_fixup_bus (struct pc
 void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
                                       struct pbus_set_ranges_data * ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 /*
--- 2.5.14/arch/ppc64/kernel/pci.c Fri May 3 04:22:47 2002
+++ linux/arch/ppc64/kernel/pci.c Mon May 6 21:24:50 2002
@@ -180,7 +180,8 @@ pcibios_fixup_resources(struct pci_dev*
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         struct pci_dev *dev = data;
 
--- 2.5.14/arch/sh/kernel/pci_st40.c Fri May 3 04:22:56 2002
+++ linux/arch/sh/kernel/pci_st40.c Sun May 5 18:40:21 2002
@@ -414,10 +414,6 @@ void __init
 pcibios_fixup_pbus_ranges(struct pci_bus *bus,
                           struct pbus_set_ranges_data *ranges)
 {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
 }
 
 void __init pcibios_init(void)
--- 2.5.14/arch/sh/kernel/pcibios.c Fri May 3 04:22:47 2002
+++ linux/arch/sh/kernel/pcibios.c Mon May 6 21:23:52 2002
@@ -60,7 +60,8 @@ pcibios_update_resource(struct pci_dev *
  * addresses to be allocated in the 0x000-0x0ff region
  * modulo 0x400.
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
 {
         if (res->flags & IORESOURCE_IO) {
                 unsigned long start = res->start;
--- 2.5.14/arch/parisc/kernel/pci.c Fri May 3 04:22:38 2002
+++ linux/arch/parisc/kernel/pci.c Sun May 5 18:40:21 2002
@@ -337,13 +337,15 @@ void pcibios_fixup_pbus_ranges(
 ** than res->start.
 */
 void __devinit
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long alignment)
 {
         unsigned long mask, align;
 
- DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx)\n",
+ DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
                 ((struct pci_dev *) data)->slot_name,
- res->parent, res->start, res->end, (int) res->flags, size);
+ res->parent, res->start, res->end,
+ (int) res->flags, size, alignment);
 
         /* has resource already been aligned/assigned? */
         if (res->parent)
@@ -400,11 +402,11 @@ pcibios_size_bridge(struct pci_bus *bus,
 
                         if (res.flags & IORESOURCE_IO) {
                                 res.start = inner.io_end;
- pcibios_align_resource(dev, &res, size);
+ pcibios_align_resource(dev, &res, size, 0);
                                 inner.io_end += res.start + size;
                         } else if (res.flags & IORESOURCE_MEM) {
                                 res.start = inner.mem_end;
- pcibios_align_resource(dev, &res, size);
+ pcibios_align_resource(dev, &res, size, 0);
                                 inner.mem_end = res.start + size;
                         }
 
--- 2.5.14/include/linux/ioport.h Fri May 3 04:22:44 2002
+++ linux/include/linux/ioport.h Sun May 5 18:40:21 2002
@@ -92,7 +92,8 @@ extern int allocate_resource(struct reso
                              unsigned long size,
                              unsigned long min, unsigned long max,
                              unsigned long align,
- void (*alignf)(void *, struct resource *, unsigned long),
+ void (*alignf)(void *, struct resource *,
+ unsigned long, unsigned long),
                              void *alignf_data);
 
 /* Convenience shorthand with allocation */
--- 2.5.14/include/linux/pci.h Fri May 3 04:22:52 2002
+++ linux/include/linux/pci.h Mon May 6 21:34:29 2002
@@ -501,7 +501,8 @@ int pcibios_enable_device(struct pci_dev
 char *pcibios_setup (char *str);
 
 /* Used only when drivers/pci/setup.c is used */
-void pcibios_align_resource(void *, struct resource *, unsigned long);
+void pcibios_align_resource(void *, struct resource *,
+ unsigned long, unsigned long);
 void pcibios_update_resource(struct pci_dev *, struct resource *,
                              struct resource *, int);
 void pcibios_update_irq(struct pci_dev *, int irq);
--- 2.5.14/drivers/pci/setup-res.c Fri May 3 04:22:47 2002
+++ linux/drivers/pci/setup-res.c Mon May 6 21:34:29 2002
@@ -69,6 +69,7 @@ static int pci_assign_bus_resource(const
         unsigned int type_mask,
         int resno)
 {
+ unsigned long align;
         int i;
 
         type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
@@ -81,12 +82,20 @@ static int pci_assign_bus_resource(const
                 if ((res->flags ^ r->flags) & type_mask)
                         continue;
 
- /* We cannot allocate a non-prefetching resource from a pre-fetching area */
- if ((r->flags & IORESOURCE_PREFETCH) && !(res->flags & IORESOURCE_PREFETCH))
+ /* We cannot allocate a non-prefetching resource
+ from a pre-fetching area */
+ if ((r->flags & IORESOURCE_PREFETCH) &&
+ !(res->flags & IORESOURCE_PREFETCH))
                         continue;
 
+ /* 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;
+
                 /* Ok, try it out.. */
- if (allocate_resource(r, res, size, min, -1, size, pcibios_align_resource, dev) < 0)
+ if (allocate_resource(r, res, size, min, -1, align,
+ pcibios_align_resource, dev) < 0)
                         continue;
 
                 /* Update PCI config space. */
--- 2.5.14/kernel/resource.c Fri May 3 04:22:41 2002
+++ linux/kernel/resource.c Sun May 5 18:40:21 2002
@@ -152,7 +152,8 @@ static int find_resource(struct resource
                          unsigned long size,
                          unsigned long min, unsigned long max,
                          unsigned long align,
- void (*alignf)(void *, struct resource *, unsigned long),
+ void (*alignf)(void *, struct resource *,
+ unsigned long, unsigned long),
                          void *alignf_data)
 {
         struct resource *this = root->child;
@@ -169,7 +170,7 @@ static int find_resource(struct resource
                         new->end = max;
                 new->start = (new->start + align - 1) & ~(align - 1);
                 if (alignf)
- alignf(alignf_data, new, size);
+ alignf(alignf_data, new, size, align);
                 if (new->start < new->end && new->end - new->start + 1 >= size) {
                         new->end = new->start + size - 1;
                         return 0;
@@ -189,7 +190,8 @@ int allocate_resource(struct resource *r
                       unsigned long size,
                       unsigned long min, unsigned long max,
                       unsigned long align,
- void (*alignf)(void *, struct resource *, unsigned long),
+ void (*alignf)(void *, struct resource *,
+ unsigned long, unsigned long),
                       void *alignf_data)
 {
         int err;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 07 2002 - 22:00:30 EST