aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c92
1 files changed, 63 insertions, 29 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index 414d6fc9131e..4089d12af6e0 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -38,10 +38,6 @@ EXPORT_SYMBOL(iomem_resource);
38 38
39static DEFINE_RWLOCK(resource_lock); 39static DEFINE_RWLOCK(resource_lock);
40 40
41#ifdef CONFIG_PROC_FS
42
43enum { MAX_IORES_LEVEL = 5 };
44
45static void *r_next(struct seq_file *m, void *v, loff_t *pos) 41static void *r_next(struct seq_file *m, void *v, loff_t *pos)
46{ 42{
47 struct resource *p = v; 43 struct resource *p = v;
@@ -53,6 +49,10 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos)
53 return p->sibling; 49 return p->sibling;
54} 50}
55 51
52#ifdef CONFIG_PROC_FS
53
54enum { MAX_IORES_LEVEL = 5 };
55
56static void *r_start(struct seq_file *m, loff_t *pos) 56static void *r_start(struct seq_file *m, loff_t *pos)
57 __acquires(resource_lock) 57 __acquires(resource_lock)
58{ 58{
@@ -549,13 +549,9 @@ static void __init __reserve_region_with_split(struct resource *root,
549 } 549 }
550 550
551 if (!res) { 551 if (!res) {
552 printk(KERN_DEBUG " __reserve_region_with_split: (%s) [%llx, %llx], res: (%s) [%llx, %llx]\n",
553 conflict->name, conflict->start, conflict->end,
554 name, start, end);
555
556 /* failed, split and try again */ 552 /* failed, split and try again */
557 553
558 /* conflict coverred whole area */ 554 /* conflict covered whole area */
559 if (conflict->start <= start && conflict->end >= end) 555 if (conflict->start <= start && conflict->end >= end)
560 return; 556 return;
561 557
@@ -630,33 +626,34 @@ struct resource * __request_region(struct resource *parent,
630{ 626{
631 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); 627 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
632 628
633 if (res) { 629 if (!res)
634 res->name = name; 630 return NULL;
635 res->start = start;
636 res->end = start + n - 1;
637 res->flags = IORESOURCE_BUSY;
638 631
639 write_lock(&resource_lock); 632 res->name = name;
633 res->start = start;
634 res->end = start + n - 1;
635 res->flags = IORESOURCE_BUSY;
640 636
641 for (;;) { 637 write_lock(&resource_lock);
642 struct resource *conflict;
643 638
644 conflict = __request_resource(parent, res); 639 for (;;) {
645 if (!conflict) 640 struct resource *conflict;
646 break;
647 if (conflict != parent) {
648 parent = conflict;
649 if (!(conflict->flags & IORESOURCE_BUSY))
650 continue;
651 }
652 641
653 /* Uhhuh, that didn't work out.. */ 642 conflict = __request_resource(parent, res);
654 kfree(res); 643 if (!conflict)
655 res = NULL;
656 break; 644 break;
645 if (conflict != parent) {
646 parent = conflict;
647 if (!(conflict->flags & IORESOURCE_BUSY))
648 continue;
657 } 649 }
658 write_unlock(&resource_lock); 650
651 /* Uhhuh, that didn't work out.. */
652 kfree(res);
653 res = NULL;
654 break;
659 } 655 }
656 write_unlock(&resource_lock);
660 return res; 657 return res;
661} 658}
662EXPORT_SYMBOL(__request_region); 659EXPORT_SYMBOL(__request_region);
@@ -831,3 +828,40 @@ static int __init reserve_setup(char *str)
831} 828}
832 829
833__setup("reserve=", reserve_setup); 830__setup("reserve=", reserve_setup);
831
832/*
833 * Check if the requested addr and size spans more than any slot in the
834 * iomem resource tree.
835 */
836int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
837{
838 struct resource *p = &iomem_resource;
839 int err = 0;
840 loff_t l;
841
842 read_lock(&resource_lock);
843 for (p = p->child; p ; p = r_next(NULL, p, &l)) {
844 /*
845 * We can probably skip the resources without
846 * IORESOURCE_IO attribute?
847 */
848 if (p->start >= addr + size)
849 continue;
850 if (p->end < addr)
851 continue;
852 if (p->start <= addr && (p->end >= addr + size - 1))
853 continue;
854 printk(KERN_WARNING "resource map sanity check conflict: "
855 "0x%llx 0x%llx 0x%llx 0x%llx %s\n",
856 (unsigned long long)addr,
857 (unsigned long long)(addr + size - 1),
858 (unsigned long long)p->start,
859 (unsigned long long)p->end,
860 p->name);
861 err = -1;
862 break;
863 }
864 read_unlock(&resource_lock);
865
866 return err;
867}