From 0c22001d82cf2be6be5e46080579609cfc3519bb Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 6 Feb 2004 14:02:48 +1100 Subject: [PATCH] ppc32: Fix release_OF_resource() function. It would fail to properly release the resource if taken over by the macio device resource hierarchy. This could still use some locking, but the io resource lock isn't exported --- arch/ppc/syslib/prom.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c index c8387f1baef19..b8c15260a6cc8 100644 --- a/arch/ppc/syslib/prom.c +++ b/arch/ppc/syslib/prom.c @@ -1212,8 +1212,6 @@ find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) * Request an OF device resource. Currently handles child of PCI devices, * or other nodes attached to the root node. Ultimately, put some * link to resources in the OF node. - * WARNING: out_resource->name should be initialized before calling this - * function. */ struct resource* __openfirmware request_OF_resource(struct device_node* node, int index, const char* name_postfix) @@ -1276,7 +1274,7 @@ release_OF_resource(struct device_node* node, int index) { struct pci_dev* pcidev; u8 pci_bus, pci_devfn; - unsigned long iomask; + unsigned long iomask, start, end; struct device_node* nd; struct resource* parent; struct resource *res = NULL; @@ -1305,18 +1303,23 @@ release_OF_resource(struct device_node* node, int index) if (pcidev) parent = find_parent_pci_resource(pcidev, &node->addrs[index]); if (!parent) { - printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", node->name); return -ENODEV; } - /* Find us in the parent */ + /* Find us in the parent and its childs */ res = parent->child; + start = node->addrs[index].address; + end = start + node->addrs[index].size - 1; while (res) { - if (res->start == node->addrs[index].address && - res->end == (res->start + node->addrs[index].size - 1)) + if (res->start == start && res->end == end && + (res->flags & IORESOURCE_BUSY)) break; - res = res->sibling; + if (res->start <= start && res->end >= end) + res = res->child; + else + res = res->sibling; } if (!res) return -ENODEV; -- 2.53.0