diff options
Diffstat (limited to 'arch/ia64/pci/pci.c')
-rw-r--r-- | arch/ia64/pci/pci.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..720a861f88be 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, | 312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, |
313 | &info); | 313 | &info); |
314 | 314 | ||
315 | pbus = pci_scan_bus(bus, &pci_root_ops, controller); | 315 | pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); |
316 | if (pbus) | 316 | if (pbus) |
317 | pcibios_setup_root_windows(pbus, controller); | 317 | pcibios_setup_root_windows(pbus, controller); |
318 | 318 | ||
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, | |||
373 | res->end = region->end + offset; | 373 | res->end = region->end + offset; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | ||
377 | { | ||
378 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
379 | struct resource *devr = &dev->resource[idx]; | ||
380 | |||
381 | if (!dev->bus) | ||
382 | return 0; | ||
383 | for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { | ||
384 | struct resource *busr = dev->bus->resource[i]; | ||
385 | |||
386 | if (!busr || ((busr->flags ^ devr->flags) & type_mask)) | ||
387 | continue; | ||
388 | if ((devr->start) && (devr->start >= busr->start) && | ||
389 | (devr->end <= busr->end)) | ||
390 | return 1; | ||
391 | } | ||
392 | return 0; | ||
393 | } | ||
394 | |||
376 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 395 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
377 | { | 396 | { |
378 | struct pci_bus_region region; | 397 | struct pci_bus_region region; |
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
386 | region.start = dev->resource[i].start; | 405 | region.start = dev->resource[i].start; |
387 | region.end = dev->resource[i].end; | 406 | region.end = dev->resource[i].end; |
388 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | 407 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); |
389 | pci_claim_resource(dev, i); | 408 | if ((is_valid_resource(dev, i))) |
409 | pci_claim_resource(dev, i); | ||
390 | } | 410 | } |
391 | } | 411 | } |
392 | 412 | ||
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
398 | { | 418 | { |
399 | struct pci_dev *dev; | 419 | struct pci_dev *dev; |
400 | 420 | ||
421 | if (b->self) { | ||
422 | pci_read_bridge_bases(b); | ||
423 | pcibios_fixup_device_resources(b->self); | ||
424 | } | ||
401 | list_for_each_entry(dev, &b->devices, bus_list) | 425 | list_for_each_entry(dev, &b->devices, bus_list) |
402 | pcibios_fixup_device_resources(dev); | 426 | pcibios_fixup_device_resources(dev); |
403 | 427 | ||
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
418 | u16 cmd, old_cmd; | 442 | u16 cmd, old_cmd; |
419 | int idx; | 443 | int idx; |
420 | struct resource *r; | 444 | struct resource *r; |
445 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
421 | 446 | ||
422 | if (!dev) | 447 | if (!dev) |
423 | return -EINVAL; | 448 | return -EINVAL; |
424 | 449 | ||
425 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 450 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
426 | old_cmd = cmd; | 451 | old_cmd = cmd; |
427 | for (idx=0; idx<6; idx++) { | 452 | for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { |
428 | /* Only set up the desired resources. */ | 453 | /* Only set up the desired resources. */ |
429 | if (!(mask & (1 << idx))) | 454 | if (!(mask & (1 << idx))) |
430 | continue; | 455 | continue; |
431 | 456 | ||
432 | r = &dev->resource[idx]; | 457 | r = &dev->resource[idx]; |
458 | if (!(r->flags & type_mask)) | ||
459 | continue; | ||
460 | if ((idx == PCI_ROM_RESOURCE) && | ||
461 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
462 | continue; | ||
433 | if (!r->start && r->end) { | 463 | if (!r->start && r->end) { |
434 | printk(KERN_ERR | 464 | printk(KERN_ERR |
435 | "PCI: Device %s not available because of resource collisions\n", | 465 | "PCI: Device %s not available because of resource collisions\n", |
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
441 | if (r->flags & IORESOURCE_MEM) | 471 | if (r->flags & IORESOURCE_MEM) |
442 | cmd |= PCI_COMMAND_MEMORY; | 472 | cmd |= PCI_COMMAND_MEMORY; |
443 | } | 473 | } |
444 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
445 | cmd |= PCI_COMMAND_MEMORY; | ||
446 | if (cmd != old_cmd) { | 474 | if (cmd != old_cmd) { |
447 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | 475 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); |
448 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 476 | pci_write_config_word(dev, PCI_COMMAND, cmd); |