summaryrefslogtreecommitdiff
path: root/kernel/resource.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@debian.org>2004-02-05 23:07:04 -0800
committerDavid S. Miller <davem@kernel.bkbits.net>2004-02-05 23:07:04 -0800
commit5558ae34e874f7f50920f70d1cd97cbb07e91a93 (patch)
tree81ad9e07df9dcf7293bea79fa849a80b784f6f46 /kernel/resource.c
parentd619064c3de3cd055f41d4554c9d92526a4f33b8 (diff)
[PATCH] adjust_resource()
I need this to cope with some devices on PA-RISC and Russell also needs something like it for PCMCIA.
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index e2048de77ae3..558e5ed0abcc 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -361,6 +361,49 @@ int insert_resource(struct resource *parent, struct resource *new)
EXPORT_SYMBOL(insert_resource);
/*
+ * Given an existing resource, change its start and size to match the
+ * arguments. Returns -EBUSY if it can't fit. Existing children of
+ * the resource are assumed to be immutable.
+ */
+int adjust_resource(struct resource *res, unsigned long start, unsigned long size)
+{
+ struct resource *tmp, *parent = res->parent;
+ unsigned long end = start + size - 1;
+ int result = -EBUSY;
+
+ write_lock(&resource_lock);
+
+ if ((start < parent->start) || (end > parent->end))
+ goto out;
+
+ for (tmp = res->child; tmp; tmp = tmp->sibling) {
+ if ((tmp->start < start) || (tmp->end > end))
+ goto out;
+ }
+
+ if (res->sibling && (res->sibling->start <= end))
+ goto out;
+
+ tmp = parent->child;
+ if (tmp != res) {
+ while (tmp->sibling != res)
+ tmp = tmp->sibling;
+ if (start <= tmp->end)
+ goto out;
+ }
+
+ res->start = start;
+ res->end = end;
+ result = 0;
+
+ out:
+ write_unlock(&resource_lock);
+ return result;
+}
+
+EXPORT_SYMBOL(adjust_resource);
+
+/*
* This is compatibility stuff for IO resources.
*
* Note how this, unlike the above, knows about