diff options
Diffstat (limited to 'kernel/resource.c')
-rw-r--r-- | kernel/resource.c | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/kernel/resource.c b/kernel/resource.c index e3080fcc66a3..0dd3a857579e 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * Arbitrary resource management. | 7 | * Arbitrary resource management. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/config.h> | ||
11 | #include <linux/module.h> | 10 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
13 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
@@ -23,20 +22,18 @@ | |||
23 | 22 | ||
24 | struct resource ioport_resource = { | 23 | struct resource ioport_resource = { |
25 | .name = "PCI IO", | 24 | .name = "PCI IO", |
26 | .start = 0x0000, | 25 | .start = 0, |
27 | .end = IO_SPACE_LIMIT, | 26 | .end = IO_SPACE_LIMIT, |
28 | .flags = IORESOURCE_IO, | 27 | .flags = IORESOURCE_IO, |
29 | }; | 28 | }; |
30 | |||
31 | EXPORT_SYMBOL(ioport_resource); | 29 | EXPORT_SYMBOL(ioport_resource); |
32 | 30 | ||
33 | struct resource iomem_resource = { | 31 | struct resource iomem_resource = { |
34 | .name = "PCI mem", | 32 | .name = "PCI mem", |
35 | .start = 0UL, | 33 | .start = 0, |
36 | .end = ~0UL, | 34 | .end = -1, |
37 | .flags = IORESOURCE_MEM, | 35 | .flags = IORESOURCE_MEM, |
38 | }; | 36 | }; |
39 | |||
40 | EXPORT_SYMBOL(iomem_resource); | 37 | EXPORT_SYMBOL(iomem_resource); |
41 | 38 | ||
42 | static DEFINE_RWLOCK(resource_lock); | 39 | static DEFINE_RWLOCK(resource_lock); |
@@ -83,10 +80,10 @@ static int r_show(struct seq_file *m, void *v) | |||
83 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) | 80 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) |
84 | if (p->parent == root) | 81 | if (p->parent == root) |
85 | break; | 82 | break; |
86 | seq_printf(m, "%*s%0*lx-%0*lx : %s\n", | 83 | seq_printf(m, "%*s%0*llx-%0*llx : %s\n", |
87 | depth * 2, "", | 84 | depth * 2, "", |
88 | width, r->start, | 85 | width, (unsigned long long) r->start, |
89 | width, r->end, | 86 | width, (unsigned long long) r->end, |
90 | r->name ? r->name : "<BAD>"); | 87 | r->name ? r->name : "<BAD>"); |
91 | return 0; | 88 | return 0; |
92 | } | 89 | } |
@@ -151,8 +148,8 @@ __initcall(ioresources_init); | |||
151 | /* Return the conflict entry if you can't request it */ | 148 | /* Return the conflict entry if you can't request it */ |
152 | static struct resource * __request_resource(struct resource *root, struct resource *new) | 149 | static struct resource * __request_resource(struct resource *root, struct resource *new) |
153 | { | 150 | { |
154 | unsigned long start = new->start; | 151 | resource_size_t start = new->start; |
155 | unsigned long end = new->end; | 152 | resource_size_t end = new->end; |
156 | struct resource *tmp, **p; | 153 | struct resource *tmp, **p; |
157 | 154 | ||
158 | if (end < start) | 155 | if (end < start) |
@@ -232,15 +229,52 @@ int release_resource(struct resource *old) | |||
232 | 229 | ||
233 | EXPORT_SYMBOL(release_resource); | 230 | EXPORT_SYMBOL(release_resource); |
234 | 231 | ||
232 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
233 | /* | ||
234 | * Finds the lowest memory reosurce exists within [res->start.res->end) | ||
235 | * the caller must specify res->start, res->end, res->flags. | ||
236 | * If found, returns 0, res is overwritten, if not found, returns -1. | ||
237 | */ | ||
238 | int find_next_system_ram(struct resource *res) | ||
239 | { | ||
240 | resource_size_t start, end; | ||
241 | struct resource *p; | ||
242 | |||
243 | BUG_ON(!res); | ||
244 | |||
245 | start = res->start; | ||
246 | end = res->end; | ||
247 | |||
248 | read_lock(&resource_lock); | ||
249 | for (p = iomem_resource.child; p ; p = p->sibling) { | ||
250 | /* system ram is just marked as IORESOURCE_MEM */ | ||
251 | if (p->flags != res->flags) | ||
252 | continue; | ||
253 | if (p->start > end) { | ||
254 | p = NULL; | ||
255 | break; | ||
256 | } | ||
257 | if (p->start >= start) | ||
258 | break; | ||
259 | } | ||
260 | read_unlock(&resource_lock); | ||
261 | if (!p) | ||
262 | return -1; | ||
263 | /* copy data */ | ||
264 | res->start = p->start; | ||
265 | res->end = p->end; | ||
266 | return 0; | ||
267 | } | ||
268 | #endif | ||
269 | |||
235 | /* | 270 | /* |
236 | * Find empty slot in the resource tree given range and alignment. | 271 | * Find empty slot in the resource tree given range and alignment. |
237 | */ | 272 | */ |
238 | static int find_resource(struct resource *root, struct resource *new, | 273 | static int find_resource(struct resource *root, struct resource *new, |
239 | unsigned long size, | 274 | resource_size_t size, resource_size_t min, |
240 | unsigned long min, unsigned long max, | 275 | resource_size_t max, resource_size_t align, |
241 | unsigned long align, | ||
242 | void (*alignf)(void *, struct resource *, | 276 | void (*alignf)(void *, struct resource *, |
243 | unsigned long, unsigned long), | 277 | resource_size_t, resource_size_t), |
244 | void *alignf_data) | 278 | void *alignf_data) |
245 | { | 279 | { |
246 | struct resource *this = root->child; | 280 | struct resource *this = root->child; |
@@ -282,11 +316,10 @@ static int find_resource(struct resource *root, struct resource *new, | |||
282 | * Allocate empty slot in the resource tree given range and alignment. | 316 | * Allocate empty slot in the resource tree given range and alignment. |
283 | */ | 317 | */ |
284 | int allocate_resource(struct resource *root, struct resource *new, | 318 | int allocate_resource(struct resource *root, struct resource *new, |
285 | unsigned long size, | 319 | resource_size_t size, resource_size_t min, |
286 | unsigned long min, unsigned long max, | 320 | resource_size_t max, resource_size_t align, |
287 | unsigned long align, | ||
288 | void (*alignf)(void *, struct resource *, | 321 | void (*alignf)(void *, struct resource *, |
289 | unsigned long, unsigned long), | 322 | resource_size_t, resource_size_t), |
290 | void *alignf_data) | 323 | void *alignf_data) |
291 | { | 324 | { |
292 | int err; | 325 | int err; |
@@ -371,17 +404,15 @@ int insert_resource(struct resource *parent, struct resource *new) | |||
371 | return result; | 404 | return result; |
372 | } | 405 | } |
373 | 406 | ||
374 | EXPORT_SYMBOL(insert_resource); | ||
375 | |||
376 | /* | 407 | /* |
377 | * Given an existing resource, change its start and size to match the | 408 | * Given an existing resource, change its start and size to match the |
378 | * arguments. Returns -EBUSY if it can't fit. Existing children of | 409 | * arguments. Returns -EBUSY if it can't fit. Existing children of |
379 | * the resource are assumed to be immutable. | 410 | * the resource are assumed to be immutable. |
380 | */ | 411 | */ |
381 | int adjust_resource(struct resource *res, unsigned long start, unsigned long size) | 412 | int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size) |
382 | { | 413 | { |
383 | struct resource *tmp, *parent = res->parent; | 414 | struct resource *tmp, *parent = res->parent; |
384 | unsigned long end = start + size - 1; | 415 | resource_size_t end = start + size - 1; |
385 | int result = -EBUSY; | 416 | int result = -EBUSY; |
386 | 417 | ||
387 | write_lock(&resource_lock); | 418 | write_lock(&resource_lock); |
@@ -428,7 +459,9 @@ EXPORT_SYMBOL(adjust_resource); | |||
428 | * | 459 | * |
429 | * Release-region releases a matching busy region. | 460 | * Release-region releases a matching busy region. |
430 | */ | 461 | */ |
431 | struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name) | 462 | struct resource * __request_region(struct resource *parent, |
463 | resource_size_t start, resource_size_t n, | ||
464 | const char *name) | ||
432 | { | 465 | { |
433 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 466 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
434 | 467 | ||
@@ -464,7 +497,8 @@ struct resource * __request_region(struct resource *parent, unsigned long start, | |||
464 | 497 | ||
465 | EXPORT_SYMBOL(__request_region); | 498 | EXPORT_SYMBOL(__request_region); |
466 | 499 | ||
467 | int __check_region(struct resource *parent, unsigned long start, unsigned long n) | 500 | int __check_region(struct resource *parent, resource_size_t start, |
501 | resource_size_t n) | ||
468 | { | 502 | { |
469 | struct resource * res; | 503 | struct resource * res; |
470 | 504 | ||
@@ -479,10 +513,11 @@ int __check_region(struct resource *parent, unsigned long start, unsigned long n | |||
479 | 513 | ||
480 | EXPORT_SYMBOL(__check_region); | 514 | EXPORT_SYMBOL(__check_region); |
481 | 515 | ||
482 | void __release_region(struct resource *parent, unsigned long start, unsigned long n) | 516 | void __release_region(struct resource *parent, resource_size_t start, |
517 | resource_size_t n) | ||
483 | { | 518 | { |
484 | struct resource **p; | 519 | struct resource **p; |
485 | unsigned long end; | 520 | resource_size_t end; |
486 | 521 | ||
487 | p = &parent->child; | 522 | p = &parent->child; |
488 | end = start + n - 1; | 523 | end = start + n - 1; |
@@ -511,7 +546,9 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon | |||
511 | 546 | ||
512 | write_unlock(&resource_lock); | 547 | write_unlock(&resource_lock); |
513 | 548 | ||
514 | printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end); | 549 | printk(KERN_WARNING "Trying to free nonexistent resource " |
550 | "<%016llx-%016llx>\n", (unsigned long long)start, | ||
551 | (unsigned long long)end); | ||
515 | } | 552 | } |
516 | 553 | ||
517 | EXPORT_SYMBOL(__release_region); | 554 | EXPORT_SYMBOL(__release_region); |