linux/kernel/resource.c
<<
>>
Prefs
   1/*
   2 *      linux/kernel/resource.c
   3 *
   4 * Copyright (C) 1999   Linus Torvalds
   5 * Copyright (C) 1999   Martin Mares <mj@ucw.cz>
   6 *
   7 * Arbitrary resource management.
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/errno.h>
  12#include <linux/ioport.h>
  13#include <linux/init.h>
  14#include <linux/slab.h>
  15#include <linux/spinlock.h>
  16#include <linux/fs.h>
  17#include <linux/proc_fs.h>
  18#include <linux/seq_file.h>
  19#include <linux/device.h>
  20#include <linux/pfn.h>
  21#include <asm/io.h>
  22
  23
  24struct resource ioport_resource = {
  25        .name   = "PCI IO",
  26        .start  = 0,
  27        .end    = IO_SPACE_LIMIT,
  28        .flags  = IORESOURCE_IO,
  29};
  30EXPORT_SYMBOL(ioport_resource);
  31
  32struct resource iomem_resource = {
  33        .name   = "PCI mem",
  34        .start  = 0,
  35        .end    = -1,
  36        .flags  = IORESOURCE_MEM,
  37};
  38EXPORT_SYMBOL(iomem_resource);
  39
  40static DEFINE_RWLOCK(resource_lock);
  41
  42static void *r_next(struct seq_file *m, void *v, loff_t *pos)
  43{
  44        struct resource *p = v;
  45        (*pos)++;
  46        if (p->child)
  47                return p->child;
  48        while (!p->sibling && p->parent)
  49                p = p->parent;
  50        return p->sibling;
  51}
  52
  53#ifdef CONFIG_PROC_FS
  54
  55enum { MAX_IORES_LEVEL = 5 };
  56
  57static void *r_start(struct seq_file *m, loff_t *pos)
  58        __acquires(resource_lock)
  59{
  60        struct resource *p = m->private;
  61        loff_t l = 0;
  62        read_lock(&resource_lock);
  63        for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
  64                ;
  65        return p;
  66}
  67
  68static void r_stop(struct seq_file *m, void *v)
  69        __releases(resource_lock)
  70{
  71        read_unlock(&resource_lock);
  72}
  73
  74static int r_show(struct seq_file *m, void *v)
  75{
  76        struct resource *root = m->private;
  77        struct resource *r = v, *p;
  78        int width = root->end < 0x10000 ? 4 : 8;
  79        int depth;
  80
  81        for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
  82                if (p->parent == root)
  83                        break;
  84        seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
  85                        depth * 2, "",
  86                        width, (unsigned long long) r->start,
  87                        width, (unsigned long long) r->end,
  88                        r->name ? r->name : "<BAD>");
  89        return 0;
  90}
  91
  92static const struct seq_operations resource_op = {
  93        .start  = r_start,
  94        .next   = r_next,
  95        .stop   = r_stop,
  96        .show   = r_show,
  97};
  98
  99static int ioports_open(struct inode *inode, struct file *file)
 100{
 101        int res = seq_open(file, &resource_op);
 102        if (!res) {
 103                struct seq_file *m = file->private_data;
 104                m->private = &ioport_resource;
 105        }
 106        return res;
 107}
 108
 109static int iomem_open(struct inode *inode, struct file *file)
 110{
 111        int res = seq_open(file, &resource_op);
 112        if (!res) {
 113                struct seq_file *m = file->private_data;
 114                m->private = &iomem_resource;
 115        }
 116        return res;
 117}
 118
 119static const struct file_operations proc_ioports_operations = {
 120        .open           = ioports_open,
 121        .read           = seq_read,
 122        .llseek         = seq_lseek,
 123        .release        = seq_release,
 124};
 125
 126static const struct file_operations proc_iomem_operations = {
 127        .open           = iomem_open,
 128        .read           = seq_read,
 129        .llseek         = seq_lseek,
 130        .release        = seq_release,
 131};
 132
 133static int __init ioresources_init(void)
 134{
 135        proc_create("ioports", 0, NULL, &proc_ioports_operations);
 136        proc_create("iomem", 0, NULL, &proc_iomem_operations);
 137        return 0;
 138}
 139__initcall(ioresources_init);
 140
 141#endif /* CONFIG_PROC_FS */
 142
 143/* Return the conflict entry if you can't request it */
 144static struct resource * __request_resource(struct resource *root, struct resource *new)
 145{
 146        resource_size_t start = new->start;
 147        resource_size_t end = new->end;
 148        struct resource *tmp, **p;
 149
 150        if (end < start)
 151                return root;
 152        if (start < root->start)
 153                return root;
 154        if (end > root->end)
 155                return root;
 156        p = &root->child;
 157        for (;;) {
 158                tmp = *p;
 159                if (!tmp || tmp->start > end) {
 160                        new->sibling = tmp;
 161                        *p = new;
 162                        new->parent = root;
 163                        return NULL;
 164                }
 165                p = &tmp->sibling;
 166                if (tmp->end < start)
 167                        continue;
 168                return tmp;
 169        }
 170}
 171
 172static int __release_resource(struct resource *old)
 173{
 174        struct resource *tmp, **p;
 175
 176        p = &old->parent->child;
 177        for (;;) {
 178                tmp = *p;
 179                if (!tmp)
 180                        break;
 181                if (tmp == old) {
 182                        *p = tmp->sibling;
 183                        old->parent = NULL;
 184                        return 0;
 185                }
 186                p = &tmp->sibling;
 187        }
 188        return -EINVAL;
 189}
 190
 191/**
 192 * request_resource - request and reserve an I/O or memory resource
 193 * @root: root resource descriptor
 194 * @new: resource descriptor desired by caller
 195 *
 196 * Returns 0 for success, negative error code on error.
 197 */
 198int request_resource(struct resource *root, struct resource *new)
 199{
 200        struct resource *conflict;
 201
 202        write_lock(&resource_lock);
 203        conflict = __request_resource(root, new);
 204        write_unlock(&resource_lock);
 205        return conflict ? -EBUSY : 0;
 206}
 207
 208EXPORT_SYMBOL(request_resource);
 209
 210/**
 211 * release_resource - release a previously reserved resource
 212 * @old: resource pointer
 213 */
 214int release_resource(struct resource *old)
 215{
 216        int retval;
 217
 218        write_lock(&resource_lock);
 219        retval = __release_resource(old);
 220        write_unlock(&resource_lock);
 221        return retval;
 222}
 223
 224EXPORT_SYMBOL(release_resource);
 225
 226#if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
 227/*
 228 * Finds the lowest memory reosurce exists within [res->start.res->end)
 229 * the caller must specify res->start, res->end, res->flags and "name".
 230 * If found, returns 0, res is overwritten, if not found, returns -1.
 231 */
 232static int find_next_system_ram(struct resource *res, char *name)
 233{
 234        resource_size_t start, end;
 235        struct resource *p;
 236
 237        BUG_ON(!res);
 238
 239        start = res->start;
 240        end = res->end;
 241        BUG_ON(start >= end);
 242
 243        read_lock(&resource_lock);
 244        for (p = iomem_resource.child; p ; p = p->sibling) {
 245                /* system ram is just marked as IORESOURCE_MEM */
 246                if (p->flags != res->flags)
 247                        continue;
 248                if (name && strcmp(p->name, name))
 249                        continue;
 250                if (p->start > end) {
 251                        p = NULL;
 252                        break;
 253                }
 254                if ((p->end >= start) && (p->start < end))
 255                        break;
 256        }
 257        read_unlock(&resource_lock);
 258        if (!p)
 259                return -1;
 260        /* copy data */
 261        if (res->start < p->start)
 262                res->start = p->start;
 263        if (res->end > p->end)
 264                res->end = p->end;
 265        return 0;
 266}
 267
 268/*
 269 * This function calls callback against all memory range of "System RAM"
 270 * which are marked as IORESOURCE_MEM and IORESOUCE_BUSY.
 271 * Now, this function is only for "System RAM".
 272 */
 273int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
 274                void *arg, int (*func)(unsigned long, unsigned long, void *))
 275{
 276        struct resource res;
 277        unsigned long pfn, len;
 278        u64 orig_end;
 279        int ret = -1;
 280
 281        res.start = (u64) start_pfn << PAGE_SHIFT;
 282        res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
 283        res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 284        orig_end = res.end;
 285        while ((res.start < res.end) &&
 286                (find_next_system_ram(&res, "System RAM") >= 0)) {
 287                pfn = (unsigned long)(res.start >> PAGE_SHIFT);
 288                len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT);
 289                ret = (*func)(pfn, len, arg);
 290                if (ret)
 291                        break;
 292                res.start = res.end + 1;
 293                res.end = orig_end;
 294        }
 295        return ret;
 296}
 297
 298#endif
 299
 300/*
 301 * Find empty slot in the resource tree given range and alignment.
 302 */
 303static int find_resource(struct resource *root, struct resource *new,
 304                         resource_size_t size, resource_size_t min,
 305                         resource_size_t max, resource_size_t align,
 306                         void (*alignf)(void *, struct resource *,
 307                                        resource_size_t, resource_size_t),
 308                         void *alignf_data)
 309{
 310        struct resource *this = root->child;
 311
 312        new->start = root->start;
 313        /*
 314         * Skip past an allocated resource that starts at 0, since the assignment
 315         * of this->start - 1 to new->end below would cause an underflow.
 316         */
 317        if (this && this->start == 0) {
 318                new->start = this->end + 1;
 319                this = this->sibling;
 320        }
 321        for(;;) {
 322                if (this)
 323                        new->end = this->start - 1;
 324                else
 325                        new->end = root->end;
 326                if (new->start < min)
 327                        new->start = min;
 328                if (new->end > max)
 329                        new->end = max;
 330                new->start = ALIGN(new->start, align);
 331                if (alignf)
 332                        alignf(alignf_data, new, size, align);
 333                if (new->start < new->end && new->end - new->start >= size - 1) {
 334                        new->end = new->start + size - 1;
 335                        return 0;
 336                }
 337                if (!this)
 338                        break;
 339                new->start = this->end + 1;
 340                this = this->sibling;
 341        }
 342        return -EBUSY;
 343}
 344
 345/**
 346 * allocate_resource - allocate empty slot in the resource tree given range & alignment
 347 * @root: root resource descriptor
 348 * @new: resource descriptor desired by caller
 349 * @size: requested resource region size
 350 * @min: minimum size to allocate
 351 * @max: maximum size to allocate
 352 * @align: alignment requested, in bytes
 353 * @alignf: alignment function, optional, called if not NULL
 354 * @alignf_data: arbitrary data to pass to the @alignf function
 355 */
 356int allocate_resource(struct resource *root, struct resource *new,
 357                      resource_size_t size, resource_size_t min,
 358                      resource_size_t max, resource_size_t align,
 359                      void (*alignf)(void *, struct resource *,
 360                                     resource_size_t, resource_size_t),
 361                      void *alignf_data)
 362{
 363        int err;
 364
 365        write_lock(&resource_lock);
 366        err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
 367        if (err >= 0 && __request_resource(root, new))
 368                err = -EBUSY;
 369        write_unlock(&resource_lock);
 370        return err;
 371}
 372
 373EXPORT_SYMBOL(allocate_resource);
 374
 375/*
 376 * Insert a resource into the resource tree. If successful, return NULL,
 377 * otherwise return the conflicting resource (compare to __request_resource())
 378 */
 379static struct resource * __insert_resource(struct resource *parent, struct resource *new)
 380{
 381        struct resource *first, *next;
 382
 383        for (;; parent = first) {
 384                first = __request_resource(parent, new);
 385                if (!first)
 386                        return first;
 387
 388                if (first == parent)
 389                        return first;
 390
 391                if ((first->start > new->start) || (first->end < new->end))
 392                        break;
 393                if ((first->start == new->start) && (first->end == new->end))
 394                        break;
 395        }
 396
 397        for (next = first; ; next = next->sibling) {
 398                /* Partial overlap? Bad, and unfixable */
 399                if (next->start < new->start || next->end > new->end)
 400                        return next;
 401                if (!next->sibling)
 402                        break;
 403                if (next->sibling->start > new->end)
 404                        break;
 405        }
 406
 407        new->parent = parent;
 408        new->sibling = next->sibling;
 409        new->child = first;
 410
 411        next->sibling = NULL;
 412        for (next = first; next; next = next->sibling)
 413                next->parent = new;
 414
 415        if (parent->child == first) {
 416                parent->child = new;
 417        } else {
 418                next = parent->child;
 419                while (next->sibling != first)
 420                        next = next->sibling;
 421                next->sibling = new;
 422        }
 423        return NULL;
 424}
 425
 426/**
 427 * insert_resource - Inserts a resource in the resource tree
 428 * @parent: parent of the new resource
 429 * @new: new resource to insert
 430 *
 431 * Returns 0 on success, -EBUSY if the resource can't be inserted.
 432 *
 433 * This function is equivalent to request_resource when no conflict
 434 * happens. If a conflict happens, and the conflicting resources
 435 * entirely fit within the range of the new resource, then the new
 436 * resource is inserted and the conflicting resources become children of
 437 * the new resource.
 438 */
 439int insert_resource(struct resource *parent, struct resource *new)
 440{
 441        struct resource *conflict;
 442
 443        write_lock(&resource_lock);
 444        conflict = __insert_resource(parent, new);
 445        write_unlock(&resource_lock);
 446        return conflict ? -EBUSY : 0;
 447}
 448
 449/**
 450 * insert_resource_expand_to_fit - Insert a resource into the resource tree
 451 * @root: root resource descriptor
 452 * @new: new resource to insert
 453 *
 454 * Insert a resource into the resource tree, possibly expanding it in order
 455 * to make it encompass any conflicting resources.
 456 */
 457void insert_resource_expand_to_fit(struct resource *root, struct resource *new)
 458{
 459        if (new->parent)
 460                return;
 461
 462        write_lock(&resource_lock);
 463        for (;;) {
 464                struct resource *conflict;
 465
 466                conflict = __insert_resource(root, new);
 467                if (!conflict)
 468                        break;
 469                if (conflict == root)
 470                        break;
 471
 472                /* Ok, expand resource to cover the conflict, then try again .. */
 473                if (conflict->start < new->start)
 474                        new->start = conflict->start;
 475                if (conflict->end > new->end)
 476                        new->end = conflict->end;
 477
 478                printk("Expanded resource %s due to conflict with %s\n", new->name, conflict->name);
 479        }
 480        write_unlock(&resource_lock);
 481}
 482
 483/**
 484 * adjust_resource - modify a resource's start and size
 485 * @res: resource to modify
 486 * @start: new start value
 487 * @size: new size
 488 *
 489 * Given an existing resource, change its start and size to match the
 490 * arguments.  Returns 0 on success, -EBUSY if it can't fit.
 491 * Existing children of the resource are assumed to be immutable.
 492 */
 493int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
 494{
 495        struct resource *tmp, *parent = res->parent;
 496        resource_size_t end = start + size - 1;
 497        int result = -EBUSY;
 498
 499        write_lock(&resource_lock);
 500
 501        if ((start < parent->start) || (end > parent->end))
 502                goto out;
 503
 504        for (tmp = res->child; tmp; tmp = tmp->sibling) {
 505                if ((tmp->start < start) || (tmp->end > end))
 506                        goto out;
 507        }
 508
 509        if (res->sibling && (res->sibling->start <= end))
 510                goto out;
 511
 512        tmp = parent->child;
 513        if (tmp != res) {
 514                while (tmp->sibling != res)
 515                        tmp = tmp->sibling;
 516                if (start <= tmp->end)
 517                        goto out;
 518        }
 519
 520        res->start = start;
 521        res->end = end;
 522        result = 0;
 523
 524 out:
 525        write_unlock(&resource_lock);
 526        return result;
 527}
 528
 529static void __init __reserve_region_with_split(struct resource *root,
 530                resource_size_t start, resource_size_t end,
 531                const char *name)
 532{
 533        struct resource *parent = root;
 534        struct resource *conflict;
 535        struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC);
 536
 537        if (!res)
 538                return;
 539
 540        res->name = name;
 541        res->start = start;
 542        res->end = end;
 543        res->flags = IORESOURCE_BUSY;
 544
 545        conflict = __request_resource(parent, res);
 546        if (!conflict)
 547                return;
 548
 549        /* failed, split and try again */
 550        kfree(res);
 551
 552        /* conflict covered whole area */
 553        if (conflict->start <= start && conflict->end >= end)
 554                return;
 555
 556        if (conflict->start > start)
 557                __reserve_region_with_split(root, start, conflict->start-1, name);
 558        if (conflict->end < end)
 559                __reserve_region_with_split(root, conflict->end+1, end, name);
 560}
 561
 562void __init reserve_region_with_split(struct resource *root,
 563                resource_size_t start, resource_size_t end,
 564                const char *name)
 565{
 566        write_lock(&resource_lock);
 567        __reserve_region_with_split(root, start, end, name);
 568        write_unlock(&resource_lock);
 569}
 570
 571EXPORT_SYMBOL(adjust_resource);
 572
 573/**
 574 * resource_alignment - calculate resource's alignment
 575 * @res: resource pointer
 576 *
 577 * Returns alignment on success, 0 (invalid alignment) on failure.
 578 */
 579resource_size_t resource_alignment(struct resource *res)
 580{
 581        switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) {
 582        case IORESOURCE_SIZEALIGN:
 583                return resource_size(res);
 584        case IORESOURCE_STARTALIGN:
 585                return res->start;
 586        default:
 587                return 0;
 588        }
 589}
 590
 591/*
 592 * This is compatibility stuff for IO resources.
 593 *
 594 * Note how this, unlike the above, knows about
 595 * the IO flag meanings (busy etc).
 596 *
 597 * request_region creates a new busy region.
 598 *
 599 * check_region returns non-zero if the area is already busy.
 600 *
 601 * release_region releases a matching busy region.
 602 */
 603
 604/**
 605 * __request_region - create a new busy resource region
 606 * @parent: parent resource descriptor
 607 * @start: resource start address
 608 * @n: resource region size
 609 * @name: reserving caller's ID string
 610 * @flags: IO resource flags
 611 */
 612struct resource * __request_region(struct resource *parent,
 613                                   resource_size_t start, resource_size_t n,
 614                                   const char *name, int flags)
 615{
 616        struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 617
 618        if (!res)
 619                return NULL;
 620
 621        res->name = name;
 622        res->start = start;
 623        res->end = start + n - 1;
 624        res->flags = IORESOURCE_BUSY;
 625        res->flags |= flags;
 626
 627        write_lock(&resource_lock);
 628
 629        for (;;) {
 630                struct resource *conflict;
 631
 632                conflict = __request_resource(parent, res);
 633                if (!conflict)
 634                        break;
 635                if (conflict != parent) {
 636                        parent = conflict;
 637                        if (!(conflict->flags & IORESOURCE_BUSY))
 638                                continue;
 639                }
 640
 641                /* Uhhuh, that didn't work out.. */
 642                kfree(res);
 643                res = NULL;
 644                break;
 645        }
 646        write_unlock(&resource_lock);
 647        return res;
 648}
 649EXPORT_SYMBOL(__request_region);
 650
 651/**
 652 * __check_region - check if a resource region is busy or free
 653 * @parent: parent resource descriptor
 654 * @start: resource start address
 655 * @n: resource region size
 656 *
 657 * Returns 0 if the region is free at the moment it is checked,
 658 * returns %-EBUSY if the region is busy.
 659 *
 660 * NOTE:
 661 * This function is deprecated because its use is racy.
 662 * Even if it returns 0, a subsequent call to request_region()
 663 * may fail because another driver etc. just allocated the region.
 664 * Do NOT use it.  It will be removed from the kernel.
 665 */
 666int __check_region(struct resource *parent, resource_size_t start,
 667                        resource_size_t n)
 668{
 669        struct resource * res;
 670
 671        res = __request_region(parent, start, n, "check-region", 0);
 672        if (!res)
 673                return -EBUSY;
 674
 675        release_resource(res);
 676        kfree(res);
 677        return 0;
 678}
 679EXPORT_SYMBOL(__check_region);
 680
 681/**
 682 * __release_region - release a previously reserved resource region
 683 * @parent: parent resource descriptor
 684 * @start: resource start address
 685 * @n: resource region size
 686 *
 687 * The described resource region must match a currently busy region.
 688 */
 689void __release_region(struct resource *parent, resource_size_t start,
 690                        resource_size_t n)
 691{
 692        struct resource **p;
 693        resource_size_t end;
 694
 695        p = &parent->child;
 696        end = start + n - 1;
 697
 698        write_lock(&resource_lock);
 699
 700        for (;;) {
 701                struct resource *res = *p;
 702
 703                if (!res)
 704                        break;
 705                if (res->start <= start && res->end >= end) {
 706                        if (!(res->flags & IORESOURCE_BUSY)) {
 707                                p = &res->child;
 708                                continue;
 709                        }
 710                        if (res->start != start || res->end != end)
 711                                break;
 712                        *p = res->sibling;
 713                        write_unlock(&resource_lock);
 714                        kfree(res);
 715                        return;
 716                }
 717                p = &res->sibling;
 718        }
 719
 720        write_unlock(&resource_lock);
 721
 722        printk(KERN_WARNING "Trying to free nonexistent resource "
 723                "<%016llx-%016llx>\n", (unsigned long long)start,
 724                (unsigned long long)end);
 725}
 726EXPORT_SYMBOL(__release_region);
 727
 728/*
 729 * Managed region resource
 730 */
 731struct region_devres {
 732        struct resource *parent;
 733        resource_size_t start;
 734        resource_size_t n;
 735};
 736
 737static void devm_region_release(struct device *dev, void *res)
 738{
 739        struct region_devres *this = res;
 740
 741        __release_region(this->parent, this->start, this->n);
 742}
 743
 744static int devm_region_match(struct device *dev, void *res, void *match_data)
 745{
 746        struct region_devres *this = res, *match = match_data;
 747
 748        return this->parent == match->parent &&
 749                this->start == match->start && this->n == match->n;
 750}
 751
 752struct resource * __devm_request_region(struct device *dev,
 753                                struct resource *parent, resource_size_t start,
 754                                resource_size_t n, const char *name)
 755{
 756        struct region_devres *dr = NULL;
 757        struct resource *res;
 758
 759        dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
 760                          GFP_KERNEL);
 761        if (!dr)
 762                return NULL;
 763
 764        dr->parent = parent;
 765        dr->start = start;
 766        dr->n = n;
 767
 768        res = __request_region(parent, start, n, name, 0);
 769        if (res)
 770                devres_add(dev, dr);
 771        else
 772                devres_free(dr);
 773
 774        return res;
 775}
 776EXPORT_SYMBOL(__devm_request_region);
 777
 778void __devm_release_region(struct device *dev, struct resource *parent,
 779                           resource_size_t start, resource_size_t n)
 780{
 781        struct region_devres match_data = { parent, start, n };
 782
 783        __release_region(parent, start, n);
 784        WARN_ON(devres_destroy(dev, devm_region_release, devm_region_match,
 785                               &match_data));
 786}
 787EXPORT_SYMBOL(__devm_release_region);
 788
 789/*
 790 * Called from init/main.c to reserve IO ports.
 791 */
 792#define MAXRESERVE 4
 793static int __init reserve_setup(char *str)
 794{
 795        static int reserved;
 796        static struct resource reserve[MAXRESERVE];
 797
 798        for (;;) {
 799                unsigned int io_start, io_num;
 800                int x = reserved;
 801
 802                if (get_option (&str, &io_start) != 2)
 803                        break;
 804                if (get_option (&str, &io_num)   == 0)
 805                        break;
 806                if (x < MAXRESERVE) {
 807                        struct resource *res = reserve + x;
 808                        res->name = "reserved";
 809                        res->start = io_start;
 810                        res->end = io_start + io_num - 1;
 811                        res->flags = IORESOURCE_BUSY;
 812                        res->child = NULL;
 813                        if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
 814                                reserved = x+1;
 815                }
 816        }
 817        return 1;
 818}
 819
 820__setup("reserve=", reserve_setup);
 821
 822/*
 823 * Check if the requested addr and size spans more than any slot in the
 824 * iomem resource tree.
 825 */
 826int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
 827{
 828        struct resource *p = &iomem_resource;
 829        int err = 0;
 830        loff_t l;
 831
 832        read_lock(&resource_lock);
 833        for (p = p->child; p ; p = r_next(NULL, p, &l)) {
 834                /*
 835                 * We can probably skip the resources without
 836                 * IORESOURCE_IO attribute?
 837                 */
 838                if (p->start >= addr + size)
 839                        continue;
 840                if (p->end < addr)
 841                        continue;
 842                if (PFN_DOWN(p->start) <= PFN_DOWN(addr) &&
 843                    PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1))
 844                        continue;
 845                /*
 846                 * if a resource is "BUSY", it's not a hardware resource
 847                 * but a driver mapping of such a resource; we don't want
 848                 * to warn for those; some drivers legitimately map only
 849                 * partial hardware resources. (example: vesafb)
 850                 */
 851                if (p->flags & IORESOURCE_BUSY)
 852                        continue;
 853
 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}
 868
 869#ifdef CONFIG_STRICT_DEVMEM
 870static int strict_iomem_checks = 1;
 871#else
 872static int strict_iomem_checks;
 873#endif
 874
 875/*
 876 * check if an address is reserved in the iomem resource tree
 877 * returns 1 if reserved, 0 if not reserved.
 878 */
 879int iomem_is_exclusive(u64 addr)
 880{
 881        struct resource *p = &iomem_resource;
 882        int err = 0;
 883        loff_t l;
 884        int size = PAGE_SIZE;
 885
 886        if (!strict_iomem_checks)
 887                return 0;
 888
 889        addr = addr & PAGE_MASK;
 890
 891        read_lock(&resource_lock);
 892        for (p = p->child; p ; p = r_next(NULL, p, &l)) {
 893                /*
 894                 * We can probably skip the resources without
 895                 * IORESOURCE_IO attribute?
 896                 */
 897                if (p->start >= addr + size)
 898                        break;
 899                if (p->end < addr)
 900                        continue;
 901                if (p->flags & IORESOURCE_BUSY &&
 902                     p->flags & IORESOURCE_EXCLUSIVE) {
 903                        err = 1;
 904                        break;
 905                }
 906        }
 907        read_unlock(&resource_lock);
 908
 909        return err;
 910}
 911
 912static int __init strict_iomem(char *str)
 913{
 914        if (strstr(str, "relaxed"))
 915                strict_iomem_checks = 0;
 916        if (strstr(str, "strict"))
 917                strict_iomem_checks = 1;
 918        return 1;
 919}
 920
 921__setup("iomem=", strict_iomem);
 922