Commit 66f1207b authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Jesse Barnes

resources: add interfaces that return conflict information

request_resource() and insert_resource() only return success or failure,
which no information about what existing resource conflicted with the
proposed new reservation.  This patch adds request_resource_conflict()
and insert_resource_conflict(), which return the conflicting resource.

Callers may use this for better error messages or to adjust the new
resource and retry the request.
Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 7c9e2b1c
...@@ -112,12 +112,14 @@ struct resource_list { ...@@ -112,12 +112,14 @@ struct resource_list {
extern struct resource ioport_resource; extern struct resource ioport_resource;
extern struct resource iomem_resource; extern struct resource iomem_resource;
extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
extern int request_resource(struct resource *root, struct resource *new); extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new); extern int release_resource(struct resource *new);
void release_child_resources(struct resource *new); void release_child_resources(struct resource *new);
extern void reserve_region_with_split(struct resource *root, extern void reserve_region_with_split(struct resource *root,
resource_size_t start, resource_size_t end, resource_size_t start, resource_size_t end,
const char *name); const char *name);
extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
extern int insert_resource(struct resource *parent, struct resource *new); extern int insert_resource(struct resource *parent, struct resource *new);
extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new, extern int allocate_resource(struct resource *root, struct resource *new,
......
...@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r) ...@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r)
} }
/** /**
* request_resource - request and reserve an I/O or memory resource * request_resource_conflict - request and reserve an I/O or memory resource
* @root: root resource descriptor * @root: root resource descriptor
* @new: resource descriptor desired by caller * @new: resource descriptor desired by caller
* *
* Returns 0 for success, negative error code on error. * Returns 0 for success, conflict resource on error.
*/ */
int request_resource(struct resource *root, struct resource *new) struct resource *request_resource_conflict(struct resource *root, struct resource *new)
{ {
struct resource *conflict; struct resource *conflict;
write_lock(&resource_lock); write_lock(&resource_lock);
conflict = __request_resource(root, new); conflict = __request_resource(root, new);
write_unlock(&resource_lock); write_unlock(&resource_lock);
return conflict;
}
/**
* request_resource - request and reserve an I/O or memory resource
* @root: root resource descriptor
* @new: resource descriptor desired by caller
*
* Returns 0 for success, negative error code on error.
*/
int request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;
conflict = request_resource_conflict(root, new);
return conflict ? -EBUSY : 0; return conflict ? -EBUSY : 0;
} }
...@@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou ...@@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
} }
/** /**
* insert_resource - Inserts a resource in the resource tree * insert_resource_conflict - Inserts resource in the resource tree
* @parent: parent of the new resource * @parent: parent of the new resource
* @new: new resource to insert * @new: new resource to insert
* *
* Returns 0 on success, -EBUSY if the resource can't be inserted. * Returns 0 on success, conflict resource if the resource can't be inserted.
* *
* This function is equivalent to request_resource when no conflict * This function is equivalent to request_resource_conflict when no conflict
* happens. If a conflict happens, and the conflicting resources * happens. If a conflict happens, and the conflicting resources
* entirely fit within the range of the new resource, then the new * entirely fit within the range of the new resource, then the new
* resource is inserted and the conflicting resources become children of * resource is inserted and the conflicting resources become children of
* the new resource. * the new resource.
*/ */
int insert_resource(struct resource *parent, struct resource *new) struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
{ {
struct resource *conflict; struct resource *conflict;
write_lock(&resource_lock); write_lock(&resource_lock);
conflict = __insert_resource(parent, new); conflict = __insert_resource(parent, new);
write_unlock(&resource_lock); write_unlock(&resource_lock);
return conflict;
}
/**
* 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.
*/
int insert_resource(struct resource *parent, struct resource *new)
{
struct resource *conflict;
conflict = insert_resource_conflict(parent, new);
return conflict ? -EBUSY : 0; return conflict ? -EBUSY : 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment