Resource manager patch

Martin Mares (mj@ucw.cz)
Thu, 5 Aug 1999 22:10:32 +0200


Hello Linus,

There is a small patch to the new resource manager code (against pre-2.3.13-6):

o Implemented a function for allocation of empty resource
block given upper and lower bound, alignment and size.
o The new request_region function sometimes forgot to set
the parent of the resource, causing release_region to crash.
o If an address greater than 0x10000 is given in "reserve=...",
it's interpreted as a memory address.

Have a nice day
Martin

diff -uN linux-2.3.13-pre6/arch/alpha/config.in rsrc/arch/alpha/config.in
--- linux-2.3.13-pre6/kernel/resource.c Thu Aug 5 20:53:51 1999
+++ rsrc/kernel/resource.c Thu Aug 5 22:03:10 1999
@@ -2,6 +2,7 @@
* linux/kernel/resource.c
*
* Copyright (C) 1999 Linus Torvalds
+ * Copyright (C) 1999 Martin Mares <mj@ucw.cz>
*
* Arbitrary resource management.
*/
@@ -121,6 +122,59 @@
}

/*
+ * Find empty slot in the resource tree given range and alignment.
+ */
+static int find_resource(struct resource *root, struct resource *new,
+ unsigned long size,
+ unsigned long min, unsigned long max,
+ unsigned long align)
+{
+ struct resource *this = root->child;
+ unsigned long start, end;
+
+ start = root->start;
+ for(;;) {
+ if (this)
+ end = this->start;
+ else
+ end = root->end;
+ if (start < min)
+ start = min;
+ if (end > max)
+ end = max;
+ start = (start + align - 1) & ~(align - 1);
+ if (start < end && end - start + 1 >= size) {
+ new->start = start;
+ new->end = start + size - 1;
+ return 0;
+ }
+ if (!this)
+ break;
+ start = this->end + 1;
+ this = this->sibling;
+ }
+ return -EBUSY;
+}
+
+/*
+ * Allocate empty slot in the resource tree given range and alignment.
+ */
+int allocate_resource(struct resource *root, struct resource *new,
+ unsigned long size,
+ unsigned long min, unsigned long max,
+ unsigned long align)
+{
+ int err;
+
+ write_lock(&resource_lock);
+ err = find_resource(root, new, size, min, max, align);
+ if (err >= 0 && __request_resource(root, new))
+ err = -EBUSY;
+ write_unlock(&resource_lock);
+ return err;
+}
+
+/*
* This is compatibility stuff for IO resources.
*
* Note how this, unlike the above, knows about
@@ -161,13 +215,12 @@
res = NULL;
break;
}
+ res->parent = parent;
write_unlock(&resource_lock);
}
return res;
}

-/*
- */
int __check_region(struct resource *parent, unsigned long start, unsigned long n)
{
struct resource * res;
@@ -231,7 +284,7 @@
res->start = io_start;
res->end = io_start + io_num - 1;
res->child = NULL;
- if (request_resource(&ioport_resource, res) == 0)
+ if (request_resource(res->start > 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
reserved = x+1;
}
}
diff -uN linux-2.3.13-pre6/include/linux/ioport.h rsrc/include/linux/ioport.h
--- linux-2.3.13-pre6/include/linux/ioport.h Thu Aug 5 20:53:50 1999
+++ rsrc/include/linux/ioport.h Thu Aug 5 21:11:34 1999
@@ -37,6 +37,10 @@

extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
+extern int allocate_resource(struct resource *root, struct resource *new,
+ unsigned long size,
+ unsigned long min, unsigned long max,
+ unsigned long align);

/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/