Subject: [PATCH] resources: Update registered resource start/end in tree. Need to check if the new range is 1. fully covered by parent resource if it exists 2. not overlapped with sibling resources if they exist. 3. fully covering chilren resources if they exist. Signed-off-by: Yinghai Lu Cc: Andrew Morton --- include/linux/ioport.h | 2 ++ kernel/resource.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) Index: linux-2.6/include/linux/ioport.h =================================================================== --- linux-2.6.orig/include/linux/ioport.h +++ linux-2.6/include/linux/ioport.h @@ -141,6 +141,8 @@ extern struct resource *request_resource extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); void release_child_resources(struct resource *new); +int update_resource(struct resource *r, resource_size_t start, + resource_size_t end); extern void reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name); Index: linux-2.6/kernel/resource.c =================================================================== --- linux-2.6.orig/kernel/resource.c +++ linux-2.6/kernel/resource.c @@ -227,6 +227,55 @@ void release_child_resources(struct reso write_unlock(&resource_lock); } +int update_resource(struct resource *r, resource_size_t start, + resource_size_t end) +{ + int ret = 0; + struct resource *parent; + struct resource *p; + + if (start > end) + return -EINVAL; + + write_lock(&resource_lock); + parent = r->parent; + if (parent) { + if (start < parent->start || + end > parent->end) { + ret = -EINVAL; + goto out; + } + + p = parent->child; + while (p) { + if (p != r && + max_t(resource_size_t, p->start, start) <= + min_t(resource_size_t, p->end, end)) { + ret = -EINVAL; + goto out; + } + p = p->sibling; + } + } + + p = r->child; + while (p) { + if (p->start < start || p->end > end) { + ret = -EINVAL; + goto out; + } + p = p->sibling; + } + + r->start = start; + r->end = end; + +out: + write_unlock(&resource_lock); + + return ret; +} + /** * request_resource_conflict - request and reserve an I/O or memory resource * @root: root resource descriptor