aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index 4e9d87fd7bc5..9c358e263534 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r)
219} 219}
220 220
221/** 221/**
222 * request_resource - request and reserve an I/O or memory resource 222 * request_resource_conflict - request and reserve an I/O or memory resource
223 * @root: root resource descriptor 223 * @root: root resource descriptor
224 * @new: resource descriptor desired by caller 224 * @new: resource descriptor desired by caller
225 * 225 *
226 * Returns 0 for success, negative error code on error. 226 * Returns 0 for success, conflict resource on error.
227 */ 227 */
228int request_resource(struct resource *root, struct resource *new) 228struct resource *request_resource_conflict(struct resource *root, struct resource *new)
229{ 229{
230 struct resource *conflict; 230 struct resource *conflict;
231 231
232 write_lock(&resource_lock); 232 write_lock(&resource_lock);
233 conflict = __request_resource(root, new); 233 conflict = __request_resource(root, new);
234 write_unlock(&resource_lock); 234 write_unlock(&resource_lock);
235 return conflict;
236}
237
238/**
239 * request_resource - request and reserve an I/O or memory resource
240 * @root: root resource descriptor
241 * @new: resource descriptor desired by caller
242 *
243 * Returns 0 for success, negative error code on error.
244 */
245int request_resource(struct resource *root, struct resource *new)
246{
247 struct resource *conflict;
248
249 conflict = request_resource_conflict(root, new);
235 return conflict ? -EBUSY : 0; 250 return conflict ? -EBUSY : 0;
236} 251}
237 252
@@ -304,7 +319,7 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
304 void *arg, int (*func)(unsigned long, unsigned long, void *)) 319 void *arg, int (*func)(unsigned long, unsigned long, void *))
305{ 320{
306 struct resource res; 321 struct resource res;
307 unsigned long pfn, len; 322 unsigned long pfn, end_pfn;
308 u64 orig_end; 323 u64 orig_end;
309 int ret = -1; 324 int ret = -1;
310 325
@@ -314,9 +329,10 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
314 orig_end = res.end; 329 orig_end = res.end;
315 while ((res.start < res.end) && 330 while ((res.start < res.end) &&
316 (find_next_system_ram(&res, "System RAM") >= 0)) { 331 (find_next_system_ram(&res, "System RAM") >= 0)) {
317 pfn = (unsigned long)(res.start >> PAGE_SHIFT); 332 pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
318 len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT); 333 end_pfn = (res.end + 1) >> PAGE_SHIFT;
319 ret = (*func)(pfn, len, arg); 334 if (end_pfn > pfn)
335 ret = (*func)(pfn, end_pfn - pfn, arg);
320 if (ret) 336 if (ret)
321 break; 337 break;
322 res.start = res.end + 1; 338 res.start = res.end + 1;
@@ -473,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
473} 489}
474 490
475/** 491/**
476 * insert_resource - Inserts a resource in the resource tree 492 * insert_resource_conflict - Inserts resource in the resource tree
477 * @parent: parent of the new resource 493 * @parent: parent of the new resource
478 * @new: new resource to insert 494 * @new: new resource to insert
479 * 495 *
480 * Returns 0 on success, -EBUSY if the resource can't be inserted. 496 * Returns 0 on success, conflict resource if the resource can't be inserted.
481 * 497 *
482 * This function is equivalent to request_resource when no conflict 498 * This function is equivalent to request_resource_conflict when no conflict
483 * happens. If a conflict happens, and the conflicting resources 499 * happens. If a conflict happens, and the conflicting resources
484 * entirely fit within the range of the new resource, then the new 500 * entirely fit within the range of the new resource, then the new
485 * resource is inserted and the conflicting resources become children of 501 * resource is inserted and the conflicting resources become children of
486 * the new resource. 502 * the new resource.
487 */ 503 */
488int insert_resource(struct resource *parent, struct resource *new) 504struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
489{ 505{
490 struct resource *conflict; 506 struct resource *conflict;
491 507
492 write_lock(&resource_lock); 508 write_lock(&resource_lock);
493 conflict = __insert_resource(parent, new); 509 conflict = __insert_resource(parent, new);
494 write_unlock(&resource_lock); 510 write_unlock(&resource_lock);
511 return conflict;
512}
513
514/**
515 * insert_resource - Inserts a resource in the resource tree
516 * @parent: parent of the new resource
517 * @new: new resource to insert
518 *
519 * Returns 0 on success, -EBUSY if the resource can't be inserted.
520 */
521int insert_resource(struct resource *parent, struct resource *new)
522{
523 struct resource *conflict;
524
525 conflict = insert_resource_conflict(parent, new);
495 return conflict ? -EBUSY : 0; 526 return conflict ? -EBUSY : 0;
496} 527}
497 528