Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / resource.c
index da0ffd6..e3080fc 100644 (file)
@@ -39,7 +39,7 @@ struct resource iomem_resource = {
 
 EXPORT_SYMBOL(iomem_resource);
 
-static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(resource_lock);
 
 #ifdef CONFIG_PROC_FS
 
@@ -57,6 +57,7 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 }
 
 static void *r_start(struct seq_file *m, loff_t *pos)
+       __acquires(resource_lock)
 {
        struct resource *p = m->private;
        loff_t l = 0;
@@ -67,6 +68,7 @@ static void *r_start(struct seq_file *m, loff_t *pos)
 }
 
 static void r_stop(struct seq_file *m, void *v)
+       __releases(resource_lock)
 {
        read_unlock(&resource_lock);
 }
@@ -89,7 +91,7 @@ static int r_show(struct seq_file *m, void *v)
        return 0;
 }
 
-struct seq_operations resource_op = {
+static struct seq_operations resource_op = {
        .start  = r_start,
        .next   = r_next,
        .stop   = r_stop,
@@ -261,10 +263,10 @@ static int find_resource(struct resource *root, struct resource *new,
                        new->start = min;
                if (new->end > max)
                        new->end = max;
-               new->start = (new->start + align - 1) & ~(align - 1);
+               new->start = ALIGN(new->start, align);
                if (alignf)
                        alignf(alignf_data, new, size, align);
-               if (new->start < new->end && new->end - new->start + 1 >= size) {
+               if (new->start < new->end && new->end - new->start >= size - 1) {
                        new->end = new->start + size - 1;
                        return 0;
                }
@@ -315,11 +317,12 @@ EXPORT_SYMBOL(allocate_resource);
  */
 int insert_resource(struct resource *parent, struct resource *new)
 {
-       int result = 0;
+       int result;
        struct resource *first, *next;
 
        write_lock(&resource_lock);
  begin:
+       result = 0;
        first = __request_resource(parent, new);
        if (!first)
                goto out;
@@ -328,15 +331,20 @@ int insert_resource(struct resource *parent, struct resource *new)
        if (first == parent)
                goto out;
 
-       for (next = first; next->sibling; next = next->sibling)
+       /* Resource fully contained by the clashing resource? Recurse into it */
+       if (first->start <= new->start && first->end >= new->end) {
+               parent = first;
+               goto begin;
+       }
+
+       for (next = first; ; next = next->sibling) {
+               /* Partial overlap? Bad, and unfixable */
+               if (next->start < new->start || next->end > new->end)
+                       goto out;
+               if (!next->sibling)
+                       break;
                if (next->sibling->start > new->end)
                        break;
-
-       /* existing resource includes new resource */
-       if (next->end >= new->end) {
-               parent = next;
-               result = 0;
-               goto begin;
        }
 
        result = 0;
@@ -422,10 +430,9 @@ EXPORT_SYMBOL(adjust_resource);
  */
 struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name)
 {
-       struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+       struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
        if (res) {
-               memset(res, 0, sizeof(*res));
                res->name = name;
                res->start = start;
                res->end = start + n - 1;
@@ -457,7 +464,7 @@ struct resource * __request_region(struct resource *parent, unsigned long start,
 
 EXPORT_SYMBOL(__request_region);
 
-int __deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n)
+int __check_region(struct resource *parent, unsigned long start, unsigned long n)
 {
        struct resource * res;