]> git.hungrycats.org Git - linux/commitdiff
[PATCH] adjust_resource()
authorMatthew Wilcox <willy@debian.org>
Fri, 6 Feb 2004 07:07:04 +0000 (23:07 -0800)
committerDavid S. Miller <davem@kernel.bkbits.net>
Fri, 6 Feb 2004 07:07:04 +0000 (23:07 -0800)
I need this to cope with some devices on PA-RISC and Russell also needs
something like it for PCMCIA.

include/linux/ioport.h
kernel/resource.c

index 5ad913d3cd96ec7c71592a2494720d8924a37141..363aef7268c60cc7e5592937317569a16c27fdd2 100644 (file)
@@ -99,6 +99,8 @@ extern int allocate_resource(struct resource *root, struct resource *new,
                             void (*alignf)(void *, struct resource *,
                                            unsigned long, unsigned long),
                             void *alignf_data);
+int adjust_resource(struct resource *res, unsigned long start,
+                   unsigned long size);
 
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)   __request_region(&ioport_resource, (start), (n), (name))
index e2048de77ae3a274583dcea5d9110d06e87fd4f5..558e5ed0abccd24b7f10095e0a974d2001419868 100644 (file)
@@ -360,6 +360,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.
  *