aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:15:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:15:26 -0400
commit37577505ec6e67d550aa5fb452c7b45a093cc7f3 (patch)
tree44f22364883679308c51cae6ebb8d164ad3aa5d1 /arch/ia64
parent04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a (diff)
parentc4cbf6b96100bbcd5da6e38b3334901b2eaa25bf (diff)
Merge tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull ia64 IOH hotplug fixes from Tony Luck: "Series to fix IOH hotplug in ia64" * tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux: PCI: Replace printks with appropriate pr_*() PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource PCI/IA64: Add host bridge resource release for _CRS path PCI/IA64: fix memleak for create pci root bus fail PCI/IA64: Allocate pci_root_info instead of using stack PCI/IA64: embed pci hostbridge resources into pci_root_info PCI/IA64: SN: use normal resource instead of pci_window PCI/IA64: SN: remove sn_pci_window_fixup()
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/include/asm/pci.h10
-rw-r--r--arch/ia64/pci/pci.c239
-rw-r--r--arch/ia64/sn/kernel/io_init.c109
3 files changed, 195 insertions, 163 deletions
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 5e04b591e423..80775f55f03f 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -89,9 +89,9 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
89#define pci_legacy_read platform_pci_legacy_read 89#define pci_legacy_read platform_pci_legacy_read
90#define pci_legacy_write platform_pci_legacy_write 90#define pci_legacy_write platform_pci_legacy_write
91 91
92struct pci_window { 92struct iospace_resource {
93 struct resource resource; 93 struct list_head list;
94 u64 offset; 94 struct resource res;
95}; 95};
96 96
97struct pci_controller { 97struct pci_controller {
@@ -100,12 +100,10 @@ struct pci_controller {
100 int segment; 100 int segment;
101 int node; /* nearest node with memory or -1 for global allocation */ 101 int node; /* nearest node with memory or -1 for global allocation */
102 102
103 unsigned int windows;
104 struct pci_window *window;
105
106 void *platform_data; 103 void *platform_data;
107}; 104};
108 105
106
109#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata) 107#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
110#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment) 108#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
111 109
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index de1474ff0bc5..2326790b7d8b 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -134,6 +134,10 @@ struct pci_root_info {
134 struct acpi_device *bridge; 134 struct acpi_device *bridge;
135 struct pci_controller *controller; 135 struct pci_controller *controller;
136 struct list_head resources; 136 struct list_head resources;
137 struct resource *res;
138 resource_size_t *res_offset;
139 unsigned int res_num;
140 struct list_head io_resources;
137 char *name; 141 char *name;
138}; 142};
139 143
@@ -153,7 +157,7 @@ new_space (u64 phys_base, int sparse)
153 return i; 157 return i;
154 158
155 if (num_io_spaces == MAX_IO_SPACES) { 159 if (num_io_spaces == MAX_IO_SPACES) {
156 printk(KERN_ERR "PCI: Too many IO port spaces " 160 pr_err("PCI: Too many IO port spaces "
157 "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES); 161 "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
158 return ~0; 162 return ~0;
159 } 163 }
@@ -168,25 +172,22 @@ new_space (u64 phys_base, int sparse)
168static u64 add_io_space(struct pci_root_info *info, 172static u64 add_io_space(struct pci_root_info *info,
169 struct acpi_resource_address64 *addr) 173 struct acpi_resource_address64 *addr)
170{ 174{
175 struct iospace_resource *iospace;
171 struct resource *resource; 176 struct resource *resource;
172 char *name; 177 char *name;
173 unsigned long base, min, max, base_port; 178 unsigned long base, min, max, base_port;
174 unsigned int sparse = 0, space_nr, len; 179 unsigned int sparse = 0, space_nr, len;
175 180
176 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 181 len = strlen(info->name) + 32;
177 if (!resource) { 182 iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
178 printk(KERN_ERR "PCI: No memory for %s I/O port space\n", 183 if (!iospace) {
179 info->name); 184 dev_err(&info->bridge->dev,
185 "PCI: No memory for %s I/O port space\n",
186 info->name);
180 goto out; 187 goto out;
181 } 188 }
182 189
183 len = strlen(info->name) + 32; 190 name = (char *)(iospace + 1);
184 name = kzalloc(len, GFP_KERNEL);
185 if (!name) {
186 printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
187 info->name);
188 goto free_resource;
189 }
190 191
191 min = addr->minimum; 192 min = addr->minimum;
192 max = min + addr->address_length - 1; 193 max = min + addr->address_length - 1;
@@ -195,7 +196,7 @@ static u64 add_io_space(struct pci_root_info *info,
195 196
196 space_nr = new_space(addr->translation_offset, sparse); 197 space_nr = new_space(addr->translation_offset, sparse);
197 if (space_nr == ~0) 198 if (space_nr == ~0)
198 goto free_name; 199 goto free_resource;
199 200
200 base = __pa(io_space[space_nr].mmio_base); 201 base = __pa(io_space[space_nr].mmio_base);
201 base_port = IO_SPACE_BASE(space_nr); 202 base_port = IO_SPACE_BASE(space_nr);
@@ -210,18 +211,23 @@ static u64 add_io_space(struct pci_root_info *info,
210 if (space_nr == 0) 211 if (space_nr == 0)
211 sparse = 1; 212 sparse = 1;
212 213
214 resource = &iospace->res;
213 resource->name = name; 215 resource->name = name;
214 resource->flags = IORESOURCE_MEM; 216 resource->flags = IORESOURCE_MEM;
215 resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min); 217 resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
216 resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max); 218 resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
217 insert_resource(&iomem_resource, resource); 219 if (insert_resource(&iomem_resource, resource)) {
220 dev_err(&info->bridge->dev,
221 "can't allocate host bridge io space resource %pR\n",
222 resource);
223 goto free_resource;
224 }
218 225
226 list_add_tail(&iospace->list, &info->io_resources);
219 return base_port; 227 return base_port;
220 228
221free_name:
222 kfree(name);
223free_resource: 229free_resource:
224 kfree(resource); 230 kfree(iospace);
225out: 231out:
226 return ~0; 232 return ~0;
227} 233}
@@ -265,7 +271,7 @@ static acpi_status count_window(struct acpi_resource *resource, void *data)
265static acpi_status add_window(struct acpi_resource *res, void *data) 271static acpi_status add_window(struct acpi_resource *res, void *data)
266{ 272{
267 struct pci_root_info *info = data; 273 struct pci_root_info *info = data;
268 struct pci_window *window; 274 struct resource *resource;
269 struct acpi_resource_address64 addr; 275 struct acpi_resource_address64 addr;
270 acpi_status status; 276 acpi_status status;
271 unsigned long flags, offset = 0; 277 unsigned long flags, offset = 0;
@@ -289,55 +295,146 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
289 } else 295 } else
290 return AE_OK; 296 return AE_OK;
291 297
292 window = &info->controller->window[info->controller->windows++]; 298 resource = &info->res[info->res_num];
293 window->resource.name = info->name; 299 resource->name = info->name;
294 window->resource.flags = flags; 300 resource->flags = flags;
295 window->resource.start = addr.minimum + offset; 301 resource->start = addr.minimum + offset;
296 window->resource.end = window->resource.start + addr.address_length - 1; 302 resource->end = resource->start + addr.address_length - 1;
297 window->offset = offset; 303 info->res_offset[info->res_num] = offset;
298 304
299 if (insert_resource(root, &window->resource)) { 305 if (insert_resource(root, resource)) {
300 dev_err(&info->bridge->dev, 306 dev_err(&info->bridge->dev,
301 "can't allocate host bridge window %pR\n", 307 "can't allocate host bridge window %pR\n",
302 &window->resource); 308 resource);
303 } else { 309 } else {
304 if (offset) 310 if (offset)
305 dev_info(&info->bridge->dev, "host bridge window %pR " 311 dev_info(&info->bridge->dev, "host bridge window %pR "
306 "(PCI address [%#llx-%#llx])\n", 312 "(PCI address [%#llx-%#llx])\n",
307 &window->resource, 313 resource,
308 window->resource.start - offset, 314 resource->start - offset,
309 window->resource.end - offset); 315 resource->end - offset);
310 else 316 else
311 dev_info(&info->bridge->dev, 317 dev_info(&info->bridge->dev,
312 "host bridge window %pR\n", 318 "host bridge window %pR\n", resource);
313 &window->resource);
314 } 319 }
315
316 /* HP's firmware has a hack to work around a Windows bug. 320 /* HP's firmware has a hack to work around a Windows bug.
317 * Ignore these tiny memory ranges */ 321 * Ignore these tiny memory ranges */
318 if (!((window->resource.flags & IORESOURCE_MEM) && 322 if (!((resource->flags & IORESOURCE_MEM) &&
319 (window->resource.end - window->resource.start < 16))) 323 (resource->end - resource->start < 16)))
320 pci_add_resource_offset(&info->resources, &window->resource, 324 pci_add_resource_offset(&info->resources, resource,
321 window->offset); 325 info->res_offset[info->res_num]);
322 326
327 info->res_num++;
323 return AE_OK; 328 return AE_OK;
324} 329}
325 330
331static void free_pci_root_info_res(struct pci_root_info *info)
332{
333 struct iospace_resource *iospace, *tmp;
334
335 list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
336 kfree(iospace);
337
338 kfree(info->name);
339 kfree(info->res);
340 info->res = NULL;
341 kfree(info->res_offset);
342 info->res_offset = NULL;
343 info->res_num = 0;
344 kfree(info->controller);
345 info->controller = NULL;
346}
347
348static void __release_pci_root_info(struct pci_root_info *info)
349{
350 int i;
351 struct resource *res;
352 struct iospace_resource *iospace;
353
354 list_for_each_entry(iospace, &info->io_resources, list)
355 release_resource(&iospace->res);
356
357 for (i = 0; i < info->res_num; i++) {
358 res = &info->res[i];
359
360 if (!res->parent)
361 continue;
362
363 if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
364 continue;
365
366 release_resource(res);
367 }
368
369 free_pci_root_info_res(info);
370 kfree(info);
371}
372
373static void release_pci_root_info(struct pci_host_bridge *bridge)
374{
375 struct pci_root_info *info = bridge->release_data;
376
377 __release_pci_root_info(info);
378}
379
380static int
381probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
382 int busnum, int domain)
383{
384 char *name;
385
386 name = kmalloc(16, GFP_KERNEL);
387 if (!name)
388 return -ENOMEM;
389
390 sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
391 info->bridge = device;
392 info->name = name;
393
394 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
395 &info->res_num);
396 if (info->res_num) {
397 info->res =
398 kzalloc_node(sizeof(*info->res) * info->res_num,
399 GFP_KERNEL, info->controller->node);
400 if (!info->res) {
401 kfree(name);
402 return -ENOMEM;
403 }
404
405 info->res_offset =
406 kzalloc_node(sizeof(*info->res_offset) * info->res_num,
407 GFP_KERNEL, info->controller->node);
408 if (!info->res_offset) {
409 kfree(name);
410 kfree(info->res);
411 info->res = NULL;
412 return -ENOMEM;
413 }
414
415 info->res_num = 0;
416 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
417 add_window, info);
418 } else
419 kfree(name);
420
421 return 0;
422}
423
326struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) 424struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
327{ 425{
328 struct acpi_device *device = root->device; 426 struct acpi_device *device = root->device;
329 int domain = root->segment; 427 int domain = root->segment;
330 int bus = root->secondary.start; 428 int bus = root->secondary.start;
331 struct pci_controller *controller; 429 struct pci_controller *controller;
332 unsigned int windows = 0; 430 struct pci_root_info *info = NULL;
333 struct pci_root_info info; 431 int busnum = root->secondary.start;
334 struct pci_bus *pbus; 432 struct pci_bus *pbus;
335 char *name; 433 int pxm, ret;
336 int pxm;
337 434
338 controller = alloc_pci_controller(domain); 435 controller = alloc_pci_controller(domain);
339 if (!controller) 436 if (!controller)
340 goto out1; 437 return NULL;
341 438
342 controller->acpi_handle = device->handle; 439 controller->acpi_handle = device->handle;
343 440
@@ -347,29 +444,27 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
347 controller->node = pxm_to_node(pxm); 444 controller->node = pxm_to_node(pxm);
348#endif 445#endif
349 446
350 INIT_LIST_HEAD(&info.resources); 447 info = kzalloc(sizeof(*info), GFP_KERNEL);
351 /* insert busn resource at first */ 448 if (!info) {
352 pci_add_resource(&info.resources, &root->secondary); 449 dev_err(&device->dev,
353 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, 450 "pci_bus %04x:%02x: ignored (out of memory)\n",
354 &windows); 451 domain, busnum);
355 if (windows) { 452 kfree(controller);
356 controller->window = 453 return NULL;
357 kzalloc_node(sizeof(*controller->window) * windows,
358 GFP_KERNEL, controller->node);
359 if (!controller->window)
360 goto out2;
361
362 name = kmalloc(16, GFP_KERNEL);
363 if (!name)
364 goto out3;
365
366 sprintf(name, "PCI Bus %04x:%02x", domain, bus);
367 info.bridge = device;
368 info.controller = controller;
369 info.name = name;
370 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
371 add_window, &info);
372 } 454 }
455
456 info->controller = controller;
457 INIT_LIST_HEAD(&info->io_resources);
458 INIT_LIST_HEAD(&info->resources);
459
460 ret = probe_pci_root_info(info, device, busnum, domain);
461 if (ret) {
462 kfree(info->controller);
463 kfree(info);
464 return NULL;
465 }
466 /* insert busn resource at first */
467 pci_add_resource(&info->resources, &root->secondary);
373 /* 468 /*
374 * See arch/x86/pci/acpi.c. 469 * See arch/x86/pci/acpi.c.
375 * The desired pci bus might already be scanned in a quirk. We 470 * The desired pci bus might already be scanned in a quirk. We
@@ -377,21 +472,17 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
377 * such quirk. So we just ignore the case now. 472 * such quirk. So we just ignore the case now.
378 */ 473 */
379 pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller, 474 pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
380 &info.resources); 475 &info->resources);
381 if (!pbus) { 476 if (!pbus) {
382 pci_free_resource_list(&info.resources); 477 pci_free_resource_list(&info->resources);
478 __release_pci_root_info(info);
383 return NULL; 479 return NULL;
384 } 480 }
385 481
482 pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
483 release_pci_root_info, info);
386 pci_scan_child_bus(pbus); 484 pci_scan_child_bus(pbus);
387 return pbus; 485 return pbus;
388
389out3:
390 kfree(controller->window);
391out2:
392 kfree(controller);
393out1:
394 return NULL;
395} 486}
396 487
397int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) 488int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
@@ -691,7 +782,7 @@ static void __init set_pci_dfl_cacheline_size(void)
691 782
692 status = ia64_pal_cache_summary(&levels, &unique_caches); 783 status = ia64_pal_cache_summary(&levels, &unique_caches);
693 if (status != 0) { 784 if (status != 0) {
694 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed " 785 pr_err("%s: ia64_pal_cache_summary() failed "
695 "(status=%ld)\n", __func__, status); 786 "(status=%ld)\n", __func__, status);
696 return; 787 return;
697 } 788 }
@@ -699,7 +790,7 @@ static void __init set_pci_dfl_cacheline_size(void)
699 status = ia64_pal_cache_config_info(levels - 1, 790 status = ia64_pal_cache_config_info(levels - 1,
700 /* cache_type (data_or_unified)= */ 2, &cci); 791 /* cache_type (data_or_unified)= */ 2, &cci);
701 if (status != 0) { 792 if (status != 0) {
702 printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed " 793 pr_err("%s: ia64_pal_cache_config_info() failed "
703 "(status=%ld)\n", __func__, status); 794 "(status=%ld)\n", __func__, status);
704 return; 795 return;
705 } 796 }
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 238e2c511d94..2b00adedc45e 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void)
118} 118}
119 119
120/* 120/*
121 * sn_pci_legacy_window_fixup - Create PCI controller windows for 121 * sn_pci_legacy_window_fixup - Setup PCI resources for
122 * legacy IO and MEM space. This needs to 122 * legacy IO and MEM space. This needs to
123 * be done here, as the PROM does not have 123 * be done here, as the PROM does not have
124 * ACPI support defining the root buses 124 * ACPI support defining the root buses
125 * and their resources (_CRS), 125 * and their resources (_CRS),
126 */ 126 */
127static void 127static void
128sn_legacy_pci_window_fixup(struct pci_controller *controller, 128sn_legacy_pci_window_fixup(struct resource *res,
129 u64 legacy_io, u64 legacy_mem) 129 u64 legacy_io, u64 legacy_mem)
130{ 130{
131 controller->window = kcalloc(2, sizeof(struct pci_window), 131 res[0].name = "legacy_io";
132 GFP_KERNEL); 132 res[0].flags = IORESOURCE_IO;
133 BUG_ON(controller->window == NULL); 133 res[0].start = legacy_io;
134 controller->window[0].offset = legacy_io; 134 res[0].end = res[0].start + 0xffff;
135 controller->window[0].resource.name = "legacy_io"; 135 res[0].parent = &ioport_resource;
136 controller->window[0].resource.flags = IORESOURCE_IO; 136 res[1].name = "legacy_mem";
137 controller->window[0].resource.start = legacy_io; 137 res[1].flags = IORESOURCE_MEM;
138 controller->window[0].resource.end = 138 res[1].start = legacy_mem;
139 controller->window[0].resource.start + 0xffff; 139 res[1].end = res[1].start + (1024 * 1024) - 1;
140 controller->window[0].resource.parent = &ioport_resource; 140 res[1].parent = &iomem_resource;
141 controller->window[1].offset = legacy_mem;
142 controller->window[1].resource.name = "legacy_mem";
143 controller->window[1].resource.flags = IORESOURCE_MEM;
144 controller->window[1].resource.start = legacy_mem;
145 controller->window[1].resource.end =
146 controller->window[1].resource.start + (1024 * 1024) - 1;
147 controller->window[1].resource.parent = &iomem_resource;
148 controller->windows = 2;
149}
150
151/*
152 * sn_pci_window_fixup() - Create a pci_window for each device resource.
153 * It will setup pci_windows for use by
154 * pcibios_bus_to_resource(), pcibios_resource_to_bus(),
155 * etc.
156 */
157static void
158sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
159 s64 * pci_addrs)
160{
161 struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
162 unsigned int i;
163 unsigned int idx;
164 unsigned int new_count;
165 struct pci_window *new_window;
166
167 if (count == 0)
168 return;
169 idx = controller->windows;
170 new_count = controller->windows + count;
171 new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
172 BUG_ON(new_window == NULL);
173 if (controller->window) {
174 memcpy(new_window, controller->window,
175 sizeof(struct pci_window) * controller->windows);
176 kfree(controller->window);
177 }
178
179 /* Setup a pci_window for each device resource. */
180 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
181 if (pci_addrs[i] == -1)
182 continue;
183
184 new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
185 new_window[idx].resource = dev->resource[i];
186 idx++;
187 }
188
189 controller->windows = new_count;
190 controller->window = new_window;
191} 141}
192 142
193/* 143/*
@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
199void 149void
200sn_io_slot_fixup(struct pci_dev *dev) 150sn_io_slot_fixup(struct pci_dev *dev)
201{ 151{
202 unsigned int count = 0;
203 int idx; 152 int idx;
204 s64 pci_addrs[PCI_ROM_RESOURCE + 1];
205 unsigned long addr, end, size, start; 153 unsigned long addr, end, size, start;
206 struct pcidev_info *pcidev_info; 154 struct pcidev_info *pcidev_info;
207 struct sn_irq_info *sn_irq_info; 155 struct sn_irq_info *sn_irq_info;
@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
229 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { 177 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
230 178
231 if (!pcidev_info->pdi_pio_mapped_addr[idx]) { 179 if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
232 pci_addrs[idx] = -1;
233 continue; 180 continue;
234 } 181 }
235 182
@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev)
237 end = dev->resource[idx].end; 184 end = dev->resource[idx].end;
238 size = end - start; 185 size = end - start;
239 if (size == 0) { 186 if (size == 0) {
240 pci_addrs[idx] = -1;
241 continue; 187 continue;
242 } 188 }
243 pci_addrs[idx] = start;
244 count++;
245 addr = pcidev_info->pdi_pio_mapped_addr[idx]; 189 addr = pcidev_info->pdi_pio_mapped_addr[idx];
246 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; 190 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
247 dev->resource[idx].start = addr; 191 dev->resource[idx].start = addr;
@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
276 IORESOURCE_ROM_BIOS_COPY; 220 IORESOURCE_ROM_BIOS_COPY;
277 } 221 }
278 } 222 }
279 /* Create a pci_window in the pci_controller struct for
280 * each device resource.
281 */
282 if (count > 0)
283 sn_pci_window_fixup(dev, count, pci_addrs);
284 223
285 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); 224 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
286} 225}
@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
297 s64 status = 0; 236 s64 status = 0;
298 struct pci_controller *controller; 237 struct pci_controller *controller;
299 struct pcibus_bussoft *prom_bussoft_ptr; 238 struct pcibus_bussoft *prom_bussoft_ptr;
239 struct resource *res;
300 LIST_HEAD(resources); 240 LIST_HEAD(resources);
301 int i;
302 241
303 status = sal_get_pcibus_info((u64) segment, (u64) busnum, 242 status = sal_get_pcibus_info((u64) segment, (u64) busnum,
304 (u64) ia64_tpa(&prom_bussoft_ptr)); 243 (u64) ia64_tpa(&prom_bussoft_ptr));
@@ -310,19 +249,23 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
310 BUG_ON(!controller); 249 BUG_ON(!controller);
311 controller->segment = segment; 250 controller->segment = segment;
312 251
252 res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
253 BUG_ON(!res);
254
313 /* 255 /*
314 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). 256 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
315 * (platform_data will be overwritten later in sn_common_bus_fixup()) 257 * (platform_data will be overwritten later in sn_common_bus_fixup())
316 */ 258 */
317 controller->platform_data = prom_bussoft_ptr; 259 controller->platform_data = prom_bussoft_ptr;
318 260
319 sn_legacy_pci_window_fixup(controller, 261 sn_legacy_pci_window_fixup(res,
320 prom_bussoft_ptr->bs_legacy_io, 262 prom_bussoft_ptr->bs_legacy_io,
321 prom_bussoft_ptr->bs_legacy_mem); 263 prom_bussoft_ptr->bs_legacy_mem);
322 for (i = 0; i < controller->windows; i++) 264 pci_add_resource_offset(&resources, &res[0],
323 pci_add_resource_offset(&resources, 265 prom_bussoft_ptr->bs_legacy_io);
324 &controller->window[i].resource, 266 pci_add_resource_offset(&resources, &res[1],
325 controller->window[i].offset); 267 prom_bussoft_ptr->bs_legacy_mem);
268
326 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, 269 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
327 &resources); 270 &resources);
328 if (bus == NULL) 271 if (bus == NULL)
@@ -333,7 +276,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
333 return; 276 return;
334 277
335error_return: 278error_return:
336 279 kfree(res);
337 kfree(controller); 280 kfree(controller);
338 return; 281 return;
339} 282}