diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2003-10-08 00:43:15 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-10-08 00:43:15 -0700 |
| commit | 1728d00557baac4f59c8b340c615d1b57a6247bb (patch) | |
| tree | cfc5e5182f7f4844befa1d2684efc9520c10a540 /kernel/resource.c | |
| parent | 0ac8d0f1ac6fd38f4ca7f0c6c0cc05d6dcd123c1 (diff) | |
[PATCH] add insert_resource() helper function
This allows PPC to insert resource descriptors later on after boot.
Diffstat (limited to 'kernel/resource.c')
| -rw-r--r-- | kernel/resource.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/kernel/resource.c b/kernel/resource.c index 82435e127453..f5ea2bb294e1 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -279,6 +279,67 @@ int allocate_resource(struct resource *root, struct resource *new, EXPORT_SYMBOL(allocate_resource); +/** + * insert_resource - Inserts a resource in the resource tree + * @parent: parent of the new resource + * @new: new resource to insert + * + * Returns 0 on success, -EBUSY if the resource can't be inserted. + * + * This function is equivalent of request_resource when no + * conflict happens. If a conflict happens, and the conflicting + * resources entirely fit within the range of the new resource, + * then the new resource is inserted and the conflicting resources + * become childs of the new resource. + */ +int insert_resource(struct resource *parent, struct resource *new) +{ + int result = 0; + struct resource *first, *next; + + write_lock(&resource_lock); + first = __request_resource(parent, new); + if (!first) + goto out; + + result = -EBUSY; + if (first == parent) + goto out; + + for (next = first; next->sibling; next = next->sibling) + if (next->sibling->start > new->end) + break; + + /* existing resource overlaps end of new resource */ + if (next->end > new->end) + goto out; + + result = 0; + + new->parent = parent; + new->sibling = next->sibling; + new->child = first; + + next->sibling = NULL; + for (next = first; next; next = next->sibling) + next->parent = new; + + if (parent->child == first) { + parent->child = new; + } else { + next = parent->child; + while (next->sibling != first) + next = next->sibling; + next->sibling = new; + } + + out: + write_unlock(&resource_lock); + return result; +} + +EXPORT_SYMBOL(insert_resource); + /* * This is compatibility stuff for IO resources. * |
