aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-10 01:32:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 18:04:25 -0500
commitc40a22e0ce5eb400f27449e59e43d021bee58b8d (patch)
tree9335519358ff657a6a80baefd759337e324dc26d
parentf07234b66af1d1a204b9ddabdbdb312e8f1fb35e (diff)
PCI: Fix bus resource assignment on 32 bits with 64b resources
The current pci_assign_unassigned_resources() code doesn't work properly on 32 bits platforms with 64 bits resources. The main reason is the use of unsigned long in various places instead of resource_size_t. This is a pre-requisite for making powerpc use the generic code instead of its own half-useful implementation. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/setup-bus.c64
-rw-r--r--include/linux/pci.h4
2 files changed, 42 insertions, 26 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 401e03c920bd..8a7232feb553 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
89 * The IO resource is allocated a range twice as large as it 89 * The IO resource is allocated a range twice as large as it
90 * would normally need. This allows us to set both IO regs. 90 * would normally need. This allows us to set both IO regs.
91 */ 91 */
92 printk(" IO window: %08lx-%08lx\n", 92 printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
93 region.start, region.end); 93 (unsigned long)region.start,
94 (unsigned long)region.end);
94 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, 95 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
95 region.start); 96 region.start);
96 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, 97 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
99 100
100 pcibios_resource_to_bus(bridge, &region, bus->resource[1]); 101 pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
101 if (bus->resource[1]->flags & IORESOURCE_IO) { 102 if (bus->resource[1]->flags & IORESOURCE_IO) {
102 printk(" IO window: %08lx-%08lx\n", 103 printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
103 region.start, region.end); 104 (unsigned long)region.start,
105 (unsigned long)region.end);
104 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, 106 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
105 region.start); 107 region.start);
106 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, 108 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
109 111
110 pcibios_resource_to_bus(bridge, &region, bus->resource[2]); 112 pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
111 if (bus->resource[2]->flags & IORESOURCE_MEM) { 113 if (bus->resource[2]->flags & IORESOURCE_MEM) {
112 printk(" PREFETCH window: %08lx-%08lx\n", 114 printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
113 region.start, region.end); 115 (unsigned long)region.start,
116 (unsigned long)region.end);
114 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, 117 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
115 region.start); 118 region.start);
116 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, 119 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
119 122
120 pcibios_resource_to_bus(bridge, &region, bus->resource[3]); 123 pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
121 if (bus->resource[3]->flags & IORESOURCE_MEM) { 124 if (bus->resource[3]->flags & IORESOURCE_MEM) {
122 printk(" MEM window: %08lx-%08lx\n", 125 printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
123 region.start, region.end); 126 (unsigned long)region.start,
127 (unsigned long)region.end);
124 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, 128 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
125 region.start); 129 region.start);
126 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, 130 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus)
145{ 149{
146 struct pci_dev *bridge = bus->self; 150 struct pci_dev *bridge = bus->self;
147 struct pci_bus_region region; 151 struct pci_bus_region region;
148 u32 l, io_upper16; 152 u32 l, bu, lu, io_upper16;
149 153
150 DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge)); 154 DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
151 155
@@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus)
159 /* Set up upper 16 bits of I/O base/limit. */ 163 /* Set up upper 16 bits of I/O base/limit. */
160 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); 164 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
161 DBG(KERN_INFO " IO window: %04lx-%04lx\n", 165 DBG(KERN_INFO " IO window: %04lx-%04lx\n",
162 region.start, region.end); 166 (unsigned long)region.start,
167 (unsigned long)region.end);
163 } 168 }
164 else { 169 else {
165 /* Clear upper 16 bits of I/O base/limit. */ 170 /* Clear upper 16 bits of I/O base/limit. */
@@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus)
180 if (bus->resource[1]->flags & IORESOURCE_MEM) { 185 if (bus->resource[1]->flags & IORESOURCE_MEM) {
181 l = (region.start >> 16) & 0xfff0; 186 l = (region.start >> 16) & 0xfff0;
182 l |= region.end & 0xfff00000; 187 l |= region.end & 0xfff00000;
183 DBG(KERN_INFO " MEM window: %08lx-%08lx\n", 188 DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
184 region.start, region.end); 189 (unsigned long)region.start,
190 (unsigned long)region.end);
185 } 191 }
186 else { 192 else {
187 l = 0x0000fff0; 193 l = 0x0000fff0;
@@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
195 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); 201 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
196 202
197 /* Set up PREF base/limit. */ 203 /* Set up PREF base/limit. */
204 bu = lu = 0;
198 pcibios_resource_to_bus(bridge, &region, bus->resource[2]); 205 pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
199 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { 206 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
200 l = (region.start >> 16) & 0xfff0; 207 l = (region.start >> 16) & 0xfff0;
201 l |= region.end & 0xfff00000; 208 l |= region.end & 0xfff00000;
202 DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n", 209#ifdef CONFIG_RESOURCES_64BIT
203 region.start, region.end); 210 bu = region.start >> 32;
211 lu = region.end >> 32;
212#endif
213 DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
214 (unsigned long long)region.start,
215 (unsigned long long)region.end);
204 } 216 }
205 else { 217 else {
206 l = 0x0000fff0; 218 l = 0x0000fff0;
@@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
208 } 220 }
209 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); 221 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
210 222
211 /* Clear out the upper 32 bits of PREF base. */ 223 /* Set the upper 32 bits of PREF base & limit. */
212 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); 224 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
225 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
213 226
214 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); 227 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
215} 228}
@@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
323static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) 336static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
324{ 337{
325 struct pci_dev *dev; 338 struct pci_dev *dev;
326 unsigned long min_align, align, size; 339 resource_size_t min_align, align, size;
327 unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */ 340 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
328 int order, max_order; 341 int order, max_order;
329 struct resource *b_res = find_free_bus_resource(bus, type); 342 struct resource *b_res = find_free_bus_resource(bus, type);
330 343
@@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
340 353
341 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 354 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
342 struct resource *r = &dev->resource[i]; 355 struct resource *r = &dev->resource[i];
343 unsigned long r_size; 356 resource_size_t r_size;
344 357
345 if (r->parent || (r->flags & mask) != type) 358 if (r->parent || (r->flags & mask) != type)
346 continue; 359 continue;
@@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
350 order = __ffs(align) - 20; 363 order = __ffs(align) - 20;
351 if (order > 11) { 364 if (order > 11) {
352 printk(KERN_WARNING "PCI: region %s/%d " 365 printk(KERN_WARNING "PCI: region %s/%d "
353 "too large: %llx-%llx\n", 366 "too large: 0x%016llx-0x%016llx\n",
354 pci_name(dev), i, 367 pci_name(dev), i,
355 (unsigned long long)r->start, 368 (unsigned long long)r->start,
356 (unsigned long long)r->end); 369 (unsigned long long)r->end);
357 r->flags = 0; 370 r->flags = 0;
358 continue; 371 continue;
359 } 372 }
@@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
372 align = 0; 385 align = 0;
373 min_align = 0; 386 min_align = 0;
374 for (order = 0; order <= max_order; order++) { 387 for (order = 0; order <= max_order; order++) {
375 unsigned long align1 = 1UL << (order + 20); 388#ifdef CONFIG_RESOURCES_64BIT
376 389 resource_size_t align1 = 1ULL << (order + 20);
390#else
391 resource_size_t align1 = 1U << (order + 20);
392#endif
377 if (!align) 393 if (!align)
378 min_align = align1; 394 min_align = align1;
379 else if (ALIGN(align + min_align, min_align) < align1) 395 else if (ALIGN(align + min_align, min_align) < align1)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 87aab07e239a..4b4d711a5da8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -309,8 +309,8 @@ struct pci_raw_ops {
309extern struct pci_raw_ops *raw_pci_ops; 309extern struct pci_raw_ops *raw_pci_ops;
310 310
311struct pci_bus_region { 311struct pci_bus_region {
312 unsigned long start; 312 resource_size_t start;
313 unsigned long end; 313 resource_size_t end;
314}; 314};
315 315
316struct pci_dynids { 316struct pci_dynids {