diff options
author | Matthew Wilcox <matthew@wil.cx> | 2007-10-14 10:13:31 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@shortfin.cabal.ca> | 2007-10-18 15:34:22 -0400 |
commit | 9611f61eb5baf22b6b6ed46c2c196c10e1fade6a (patch) | |
tree | 30bd8d782abc42a6f8b553f4c33bbba2dc8f9a31 | |
parent | 26f0324922e50e0ef7677aaf96287b862c2fec61 (diff) |
[PARISC] Fix infinite loop in /proc/iomem
pcibios_link_hba_resources() could corrupt the resource tree by inserting
resources in the wrong place. Fix this by calling pci_claim_resource()
for PCI-PCI bridges. Delete pcibios_link_hba_resources as we shouldn't
need it any more. Also get rid of lba_claim_dev_resources() and just
call pci_claim_resource() directly.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>
-rw-r--r-- | arch/parisc/kernel/pci.c | 32 | ||||
-rw-r--r-- | drivers/parisc/lba_pci.c | 51 |
2 files changed, 7 insertions, 76 deletions
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 563df0072dee..8263d490b1b7 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
@@ -194,31 +194,6 @@ void __init pcibios_init_bus(struct pci_bus *bus) | |||
194 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); | 194 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); |
195 | } | 195 | } |
196 | 196 | ||
197 | |||
198 | /* KLUGE: Link the child and parent resources - generic PCI didn't */ | ||
199 | static void | ||
200 | pcibios_link_hba_resources( struct resource *hba_res, struct resource *r) | ||
201 | { | ||
202 | if (!r->parent) { | ||
203 | printk(KERN_EMERG "PCI: resource not parented! [%p-%p]\n", | ||
204 | (void*) r->start, (void*) r->end); | ||
205 | r->parent = hba_res; | ||
206 | |||
207 | /* reverse link is harder *sigh* */ | ||
208 | if (r->parent->child) { | ||
209 | if (r->parent->sibling) { | ||
210 | struct resource *next = r->parent->sibling; | ||
211 | while (next->sibling) | ||
212 | next = next->sibling; | ||
213 | next->sibling = r; | ||
214 | } else { | ||
215 | r->parent->sibling = r; | ||
216 | } | ||
217 | } else | ||
218 | r->parent->child = r; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | /* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */ | 197 | /* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */ |
223 | void __devinit pcibios_resource_to_bus(struct pci_dev *dev, | 198 | void __devinit pcibios_resource_to_bus(struct pci_dev *dev, |
224 | struct pci_bus_region *region, struct resource *res) | 199 | struct pci_bus_region *region, struct resource *res) |
@@ -245,13 +220,6 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev, | |||
245 | DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n", | 220 | DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n", |
246 | bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM", | 221 | bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM", |
247 | region->start, region->end); | 222 | region->start, region->end); |
248 | |||
249 | /* KLUGE ALERT | ||
250 | ** if this resource isn't linked to a "parent", then it seems | ||
251 | ** to be a child of the HBA - lets link it in. | ||
252 | */ | ||
253 | pcibios_link_hba_resources(&hba->io_space, bus->resource[0]); | ||
254 | pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]); | ||
255 | } | 223 | } |
256 | 224 | ||
257 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | 225 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 5b86ee5c1eeb..5eace9e66e14 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -557,44 +557,6 @@ lba_bios_init(void) | |||
557 | #ifdef CONFIG_64BIT | 557 | #ifdef CONFIG_64BIT |
558 | 558 | ||
559 | /* | 559 | /* |
560 | ** Determine if a device is already configured. | ||
561 | ** If so, reserve it resources. | ||
562 | ** | ||
563 | ** Read PCI cfg command register and see if I/O or MMIO is enabled. | ||
564 | ** PAT has to enable the devices it's using. | ||
565 | ** | ||
566 | ** Note: resources are fixed up before we try to claim them. | ||
567 | */ | ||
568 | static void | ||
569 | lba_claim_dev_resources(struct pci_dev *dev) | ||
570 | { | ||
571 | u16 cmd; | ||
572 | int i, srch_flags; | ||
573 | |||
574 | (void) pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
575 | |||
576 | srch_flags = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0; | ||
577 | if (cmd & PCI_COMMAND_MEMORY) | ||
578 | srch_flags |= IORESOURCE_MEM; | ||
579 | |||
580 | if (!srch_flags) | ||
581 | return; | ||
582 | |||
583 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
584 | if (dev->resource[i].flags & srch_flags) { | ||
585 | pci_claim_resource(dev, i); | ||
586 | DBG(" claimed %s %d [%lx,%lx]/%lx\n", | ||
587 | pci_name(dev), i, | ||
588 | dev->resource[i].start, | ||
589 | dev->resource[i].end, | ||
590 | dev->resource[i].flags | ||
591 | ); | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
596 | |||
597 | /* | ||
598 | * truncate_pat_collision: Deal with overlaps or outright collisions | 560 | * truncate_pat_collision: Deal with overlaps or outright collisions |
599 | * between PAT PDC reported ranges. | 561 | * between PAT PDC reported ranges. |
600 | * | 562 | * |
@@ -653,7 +615,6 @@ truncate_pat_collision(struct resource *root, struct resource *new) | |||
653 | } | 615 | } |
654 | 616 | ||
655 | #else | 617 | #else |
656 | #define lba_claim_dev_resources(dev) do { } while (0) | ||
657 | #define truncate_pat_collision(r,n) (0) | 618 | #define truncate_pat_collision(r,n) (0) |
658 | #endif | 619 | #endif |
659 | 620 | ||
@@ -684,8 +645,12 @@ lba_fixup_bus(struct pci_bus *bus) | |||
684 | ** pci_alloc_primary_bus() mangles this. | 645 | ** pci_alloc_primary_bus() mangles this. |
685 | */ | 646 | */ |
686 | if (bus->self) { | 647 | if (bus->self) { |
648 | int i; | ||
687 | /* PCI-PCI Bridge */ | 649 | /* PCI-PCI Bridge */ |
688 | pci_read_bridge_bases(bus); | 650 | pci_read_bridge_bases(bus); |
651 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
652 | pci_claim_resource(bus->self, i); | ||
653 | } | ||
689 | } else { | 654 | } else { |
690 | /* Host-PCI Bridge */ | 655 | /* Host-PCI Bridge */ |
691 | int err, i; | 656 | int err, i; |
@@ -803,6 +768,9 @@ lba_fixup_bus(struct pci_bus *bus) | |||
803 | DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX", | 768 | DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX", |
804 | res->flags, res->start, res->end); | 769 | res->flags, res->start, res->end); |
805 | } | 770 | } |
771 | if ((i != PCI_ROM_RESOURCE) || | ||
772 | (res->flags & IORESOURCE_ROM_ENABLE)) | ||
773 | pci_claim_resource(dev, i); | ||
806 | } | 774 | } |
807 | 775 | ||
808 | #ifdef FBB_SUPPORT | 776 | #ifdef FBB_SUPPORT |
@@ -814,11 +782,6 @@ lba_fixup_bus(struct pci_bus *bus) | |||
814 | bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK); | 782 | bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK); |
815 | #endif | 783 | #endif |
816 | 784 | ||
817 | if (is_pdc_pat()) { | ||
818 | /* Claim resources for PDC's devices */ | ||
819 | lba_claim_dev_resources(dev); | ||
820 | } | ||
821 | |||
822 | /* | 785 | /* |
823 | ** P2PB's have no IRQs. ignore them. | 786 | ** P2PB's have no IRQs. ignore them. |
824 | */ | 787 | */ |