linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add insert_resource()
@ 2003-10-04 22:23 Benjamin Herrenschmidt
  2003-10-05  9:18 ` [PATCH] (Updated) " Benjamin Herrenschmidt
  0 siblings, 1 reply; 2+ messages in thread
From: Benjamin Herrenschmidt @ 2003-10-04 22:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Linux Kernel list

Hi Linus !

This patch adds an insert_resource() function to kernel/resource.c,
this function behaves like request_resource(), except that if a
conflict happens and the conflicting resources fit "inside" the
new resources, the new resource is inserted and the conflicting
ones moved as childs of the new resource.

This is necessary to deal with some corner cases on the PPC arch
at least, and maybe more later, where we have some early boot code
request things like serial ports or interrupt controller, and later
on, the PCI "macio" combo-asic that really contain these gets
probed and try to creates it's own resource tree based on open
firmware.

We implemented this in the arch code previously, but we lacked
locking as the resource lock is static to kernel/resource.c, and
we had to re-implement __request_resource() which is static as
well. Mattew Willcox has the idea of making this insert_resource()
function generic (and provided the first implementation).

Please apply, future PowerMac updates will rely on this

Regards,
Ben.


--- linux-2.5/kernel/resource.c	2003-10-04 22:20:11.000000000 +0200
+++ linuxppc-2.5-benh/kernel/resource.c	2003-10-04 22:20:56.000000000 +0200
@@ -268,6 +268,59 @@
 	return err;
 }
 
+/**
+ * insert_resource - Inserts a resource between two existing resources
+ * @parent
+ * @new
+ *
+ * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ */
+int insert_resource(struct resource *parent, struct resource *new)
+{
+	int result = 0;
+	struct resource *first, *next;
+
+	write_lock(&resource_lock);
+	first = __request_resource(parent, new);
+	if (!first)
+		goto out;
+
+	result = -EBUSY;
+	if (first == parent)
+		goto out;
+
+	for (next = first; next->sibling; next = next->sibling)
+		if (next->sibling->start > new->end)
+			break;
+
+	/* existing resource overlaps end of new resource */
+	if (next->end > new->end)
+		goto out;
+
+	result = 0;
+
+	new->parent = parent;
+	new->sibling = next->sibling;
+	new->child = first;
+
+	next->sibling = NULL;
+	for (next = first; next; next = next->sibling)
+		next->parent = new;
+
+	if (parent->child == first) {
+		parent->child = new;
+	} else {
+		next = parent->child;
+		while (next->sibling != first)
+			next = next->sibling;
+		next->sibling = new;
+	}
+
+ out:
+	write_unlock(&resource_lock);
+	return result;
+}
+
 /*
  * This is compatibility stuff for IO resources.
  *
--- linux-2.5/kernel/ksyms.c	2003-10-04 22:20:11.000000000 +0200
+++ linuxppc-2.5-benh/kernel/ksyms.c	2003-10-04 23:21:20.000000000 +0200
@@ -256,6 +256,7 @@
 EXPORT_SYMBOL(request_resource);
 EXPORT_SYMBOL(release_resource);
 EXPORT_SYMBOL(allocate_resource);
+EXPORT_SYMBOL(insert_resource);
 EXPORT_SYMBOL(__request_region);
 EXPORT_SYMBOL(__check_region);
 EXPORT_SYMBOL(__release_region);
--- linux-2.5/include/linux/ioport.h	2003-10-04 22:20:17.000000000 +0200
+++ linuxppc-2.5-benh/include/linux/ioport.h	2003-10-03 14:06:46.000000000 +0200
@@ -90,6 +90,7 @@
 
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
+extern int insert_resource(struct resource *parent, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
 			     unsigned long size,
 			     unsigned long min, unsigned long max,



^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] (Updated) Add insert_resource()
  2003-10-04 22:23 [PATCH] Add insert_resource() Benjamin Herrenschmidt
@ 2003-10-05  9:18 ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Herrenschmidt @ 2003-10-05  9:18 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Linux Kernel list

Hi Linus !

The insert_resource patch has a quite weak and misleading
documentation for the insert_resource() function. Here's an
updated version that should be more useful.

Please apply as I'll need that functionality for further
PowerMac updates.

Regards,
Ben.

--- linux-2.5/kernel/resource.c	2003-10-04 22:20:11.000000000 +0200
+++ linuxppc-2.5-benh/kernel/resource.c	2003-10-05 11:14:39.000000000 +0200
@@ -268,6 +268,65 @@
 	return err;
 }
 
+/**
+ * insert_resource - Inserts a resource in the resource tree
+ * @parent: parent of the new resource
+ * @new: new resource to insert
+ *
+ * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ *
+ * This function is equivalent of request_resource when no
+ * conflict happens. If a conflict happens, and the conflicting
+ * resources entirely fit within the range of the new resource,
+ * then the new resource is inserted and the conflicting resources
+ * become childs of the new resource. 
+ */
+int insert_resource(struct resource *parent, struct resource *new)
+{
+	int result = 0;
+	struct resource *first, *next;
+
+	write_lock(&resource_lock);
+	first = __request_resource(parent, new);
+	if (!first)
+		goto out;
+
+	result = -EBUSY;
+	if (first == parent)
+		goto out;
+
+	for (next = first; next->sibling; next = next->sibling)
+		if (next->sibling->start > new->end)
+			break;
+
+	/* existing resource overlaps end of new resource */
+	if (next->end > new->end)
+		goto out;
+
+	result = 0;
+
+	new->parent = parent;
+	new->sibling = next->sibling;
+	new->child = first;
+
+	next->sibling = NULL;
+	for (next = first; next; next = next->sibling)
+		next->parent = new;
+
+	if (parent->child == first) {
+		parent->child = new;
+	} else {
+		next = parent->child;
+		while (next->sibling != first)
+			next = next->sibling;
+		next->sibling = new;
+	}
+
+ out:
+	write_unlock(&resource_lock);
+	return result;
+}
+
 /*
  * This is compatibility stuff for IO resources.
  *
--- linux-2.5/kernel/ksyms.c	2003-10-04 22:20:11.000000000 +0200
+++ linuxppc-2.5-benh/kernel/ksyms.c	2003-10-05 11:15:47.000000000 +0200
@@ -256,6 +256,7 @@
 EXPORT_SYMBOL(request_resource);
 EXPORT_SYMBOL(release_resource);
 EXPORT_SYMBOL(allocate_resource);
+EXPORT_SYMBOL(insert_resource);
 EXPORT_SYMBOL(__request_region);
 EXPORT_SYMBOL(__check_region);
 EXPORT_SYMBOL(__release_region);
--- linux-2.5/include/linux/ioport.h	2003-10-04 22:20:17.000000000 +0200
+++ linuxppc-2.5-benh/include/linux/ioport.h	2003-10-05 11:15:54.000000000 +0200
@@ -90,6 +90,7 @@
 
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
+extern int insert_resource(struct resource *parent, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
 			     unsigned long size,
 			     unsigned long min, unsigned long max,



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-10-05  9:19 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-04 22:23 [PATCH] Add insert_resource() Benjamin Herrenschmidt
2003-10-05  9:18 ` [PATCH] (Updated) " Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).