aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/bus.c')
-rw-r--r--drivers/pci/bus.c53
1 files changed, 5 insertions, 48 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 5624db8c9ad0..69546e9213dd 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -64,49 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
64 } 64 }
65} 65}
66 66
67/*
68 * Find the highest-address bus resource below the cursor "res". If the
69 * cursor is NULL, return the highest resource.
70 */
71static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
72 unsigned int type,
73 struct resource *res)
74{
75 struct resource *r, *prev = NULL;
76 int i;
77
78 pci_bus_for_each_resource(bus, r, i) {
79 if (!r)
80 continue;
81
82 if ((r->flags & IORESOURCE_TYPE_BITS) != type)
83 continue;
84
85 /* If this resource is at or past the cursor, skip it */
86 if (res) {
87 if (r == res)
88 continue;
89 if (r->end > res->end)
90 continue;
91 if (r->end == res->end && r->start > res->start)
92 continue;
93 }
94
95 if (!prev)
96 prev = r;
97
98 /*
99 * A small resource is higher than a large one that ends at
100 * the same address.
101 */
102 if (r->end > prev->end ||
103 (r->end == prev->end && r->start > prev->start))
104 prev = r;
105 }
106
107 return prev;
108}
109
110/** 67/**
111 * pci_bus_alloc_resource - allocate a resource from a parent bus 68 * pci_bus_alloc_resource - allocate a resource from a parent bus
112 * @bus: PCI bus 69 * @bus: PCI bus
@@ -132,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
132 resource_size_t), 89 resource_size_t),
133 void *alignf_data) 90 void *alignf_data)
134{ 91{
135 int ret = -ENOMEM; 92 int i, ret = -ENOMEM;
136 struct resource *r; 93 struct resource *r;
137 resource_size_t max = -1; 94 resource_size_t max = -1;
138 unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
139 95
140 type_mask |= IORESOURCE_IO | IORESOURCE_MEM; 96 type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
141 97
@@ -143,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
143 if (!(res->flags & IORESOURCE_MEM_64)) 99 if (!(res->flags & IORESOURCE_MEM_64))
144 max = PCIBIOS_MAX_MEM_32; 100 max = PCIBIOS_MAX_MEM_32;
145 101
146 /* Look for space at highest addresses first */ 102 pci_bus_for_each_resource(bus, r, i) {
147 r = pci_bus_find_resource_prev(bus, type, NULL); 103 if (!r)
148 for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { 104 continue;
105
149 /* type_mask must match */ 106 /* type_mask must match */
150 if ((res->flags ^ r->flags) & type_mask) 107 if ((res->flags ^ r->flags) & type_mask)
151 continue; 108 continue;