LCOV - code coverage report
Current view: top level - kernel - resource.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 24 429 5.6 %
Date: 2014-04-07 Functions: 6 45 13.3 %
Branches: 22 340 6.5 %

           Branch data     Line data    Source code
       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                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      11                 :            : 
      12                 :            : #include <linux/export.h>
      13                 :            : #include <linux/errno.h>
      14                 :            : #include <linux/ioport.h>
      15                 :            : #include <linux/init.h>
      16                 :            : #include <linux/slab.h>
      17                 :            : #include <linux/spinlock.h>
      18                 :            : #include <linux/fs.h>
      19                 :            : #include <linux/proc_fs.h>
      20                 :            : #include <linux/sched.h>
      21                 :            : #include <linux/seq_file.h>
      22                 :            : #include <linux/device.h>
      23                 :            : #include <linux/pfn.h>
      24                 :            : #include <linux/mm.h>
      25                 :            : #include <asm/io.h>
      26                 :            : 
      27                 :            : 
      28                 :            : struct resource ioport_resource = {
      29                 :            :         .name   = "PCI IO",
      30                 :            :         .start  = 0,
      31                 :            :         .end    = IO_SPACE_LIMIT,
      32                 :            :         .flags  = IORESOURCE_IO,
      33                 :            : };
      34                 :            : EXPORT_SYMBOL(ioport_resource);
      35                 :            : 
      36                 :            : struct resource iomem_resource = {
      37                 :            :         .name   = "PCI mem",
      38                 :            :         .start  = 0,
      39                 :            :         .end    = -1,
      40                 :            :         .flags  = IORESOURCE_MEM,
      41                 :            : };
      42                 :            : EXPORT_SYMBOL(iomem_resource);
      43                 :            : 
      44                 :            : /* constraints to be met while allocating resources */
      45                 :            : struct resource_constraint {
      46                 :            :         resource_size_t min, max, align;
      47                 :            :         resource_size_t (*alignf)(void *, const struct resource *,
      48                 :            :                         resource_size_t, resource_size_t);
      49                 :            :         void *alignf_data;
      50                 :            : };
      51                 :            : 
      52                 :            : static DEFINE_RWLOCK(resource_lock);
      53                 :            : 
      54                 :            : /*
      55                 :            :  * For memory hotplug, there is no way to free resource entries allocated
      56                 :            :  * by boot mem after the system is up. So for reusing the resource entry
      57                 :            :  * we need to remember the resource.
      58                 :            :  */
      59                 :            : static struct resource *bootmem_resource_free;
      60                 :            : static DEFINE_SPINLOCK(bootmem_resource_lock);
      61                 :            : 
      62                 :          0 : static void *r_next(struct seq_file *m, void *v, loff_t *pos)
      63                 :            : {
      64                 :            :         struct resource *p = v;
      65                 :         88 :         (*pos)++;
      66 [ #  # ][ #  # ]:         88 :         if (p->child)
         [ +  + ][ +  + ]
      67                 :            :                 return p->child;
      68 [ #  # ][ #  # ]:        108 :         while (!p->sibling && p->parent)
         [ #  # ][ #  # ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
      69                 :            :                 p = p->parent;
      70                 :            :         return p->sibling;
      71                 :            : }
      72                 :            : 
      73                 :            : #ifdef CONFIG_PROC_FS
      74                 :            : 
      75                 :            : enum { MAX_IORES_LEVEL = 5 };
      76                 :            : 
      77                 :          0 : static void *r_start(struct seq_file *m, loff_t *pos)
      78                 :            :         __acquires(resource_lock)
      79                 :            : {
      80                 :          4 :         struct resource *p = m->private;
      81                 :            :         loff_t l = 0;
      82                 :          4 :         read_lock(&resource_lock);
      83    [ + ][ +  + ]:         59 :         for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
      84                 :            :                 ;
      85                 :          0 :         return p;
      86                 :            : }
      87                 :            : 
      88                 :          0 : static void r_stop(struct seq_file *m, void *v)
      89                 :            :         __releases(resource_lock)
      90                 :            : {
      91                 :            :         read_unlock(&resource_lock);
      92                 :          4 : }
      93                 :            : 
      94                 :          0 : static int r_show(struct seq_file *m, void *v)
      95                 :            : {
      96                 :         34 :         struct resource *root = m->private;
      97                 :            :         struct resource *r = v, *p;
      98         [ +  - ]:         34 :         int width = root->end < 0x10000 ? 4 : 8;
      99                 :            :         int depth;
     100                 :            : 
     101         [ +  - ]:         45 :         for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
     102         [ +  + ]:         45 :                 if (p->parent == root)
     103                 :            :                         break;
     104         [ +  - ]:         34 :         seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
     105                 :            :                         depth * 2, "",
     106                 :         34 :                         width, (unsigned long long) r->start,
     107                 :         34 :                         width, (unsigned long long) r->end,
     108                 :         34 :                         r->name ? r->name : "<BAD>");
     109                 :         34 :         return 0;
     110                 :            : }
     111                 :            : 
     112                 :            : static const struct seq_operations resource_op = {
     113                 :            :         .start  = r_start,
     114                 :            :         .next   = r_next,
     115                 :            :         .stop   = r_stop,
     116                 :            :         .show   = r_show,
     117                 :            : };
     118                 :            : 
     119                 :          0 : static int ioports_open(struct inode *inode, struct file *file)
     120                 :            : {
     121                 :          1 :         int res = seq_open(file, &resource_op);
     122         [ +  - ]:          1 :         if (!res) {
     123                 :          1 :                 struct seq_file *m = file->private_data;
     124                 :          1 :                 m->private = &ioport_resource;
     125                 :            :         }
     126                 :          0 :         return res;
     127                 :            : }
     128                 :            : 
     129                 :          0 : static int iomem_open(struct inode *inode, struct file *file)
     130                 :            : {
     131                 :          1 :         int res = seq_open(file, &resource_op);
     132         [ +  - ]:          1 :         if (!res) {
     133                 :          1 :                 struct seq_file *m = file->private_data;
     134                 :          1 :                 m->private = &iomem_resource;
     135                 :            :         }
     136                 :          0 :         return res;
     137                 :            : }
     138                 :            : 
     139                 :            : static const struct file_operations proc_ioports_operations = {
     140                 :            :         .open           = ioports_open,
     141                 :            :         .read           = seq_read,
     142                 :            :         .llseek         = seq_lseek,
     143                 :            :         .release        = seq_release,
     144                 :            : };
     145                 :            : 
     146                 :            : static const struct file_operations proc_iomem_operations = {
     147                 :            :         .open           = iomem_open,
     148                 :            :         .read           = seq_read,
     149                 :            :         .llseek         = seq_lseek,
     150                 :            :         .release        = seq_release,
     151                 :            : };
     152                 :            : 
     153                 :          0 : static int __init ioresources_init(void)
     154                 :            : {
     155                 :            :         proc_create("ioports", 0, NULL, &proc_ioports_operations);
     156                 :            :         proc_create("iomem", 0, NULL, &proc_iomem_operations);
     157                 :          0 :         return 0;
     158                 :            : }
     159                 :            : __initcall(ioresources_init);
     160                 :            : 
     161                 :            : #endif /* CONFIG_PROC_FS */
     162                 :            : 
     163                 :          0 : static void free_resource(struct resource *res)
     164                 :            : {
     165         [ #  # ]:          0 :         if (!res)
     166                 :          0 :                 return;
     167                 :            : 
     168         [ #  # ]:          0 :         if (!PageSlab(virt_to_head_page(res))) {
     169                 :            :                 spin_lock(&bootmem_resource_lock);
     170                 :          0 :                 res->sibling = bootmem_resource_free;
     171                 :          0 :                 bootmem_resource_free = res;
     172                 :            :                 spin_unlock(&bootmem_resource_lock);
     173                 :            :         } else {
     174                 :          0 :                 kfree(res);
     175                 :            :         }
     176                 :            : }
     177                 :            : 
     178                 :          0 : static struct resource *alloc_resource(gfp_t flags)
     179                 :            : {
     180                 :            :         struct resource *res = NULL;
     181                 :            : 
     182                 :            :         spin_lock(&bootmem_resource_lock);
     183         [ #  # ]:          0 :         if (bootmem_resource_free) {
     184                 :            :                 res = bootmem_resource_free;
     185                 :          0 :                 bootmem_resource_free = res->sibling;
     186                 :            :         }
     187                 :            :         spin_unlock(&bootmem_resource_lock);
     188                 :            : 
     189         [ #  # ]:          0 :         if (res)
     190                 :          0 :                 memset(res, 0, sizeof(struct resource));
     191                 :            :         else
     192                 :            :                 res = kzalloc(sizeof(struct resource), flags);
     193                 :            : 
     194                 :          0 :         return res;
     195                 :            : }
     196                 :            : 
     197                 :            : /* Return the conflict entry if you can't request it */
     198                 :          0 : static struct resource * __request_resource(struct resource *root, struct resource *new)
     199                 :            : {
     200                 :          0 :         resource_size_t start = new->start;
     201                 :          0 :         resource_size_t end = new->end;
     202                 :            :         struct resource *tmp, **p;
     203                 :            : 
     204         [ #  # ]:          0 :         if (end < start)
     205                 :            :                 return root;
     206         [ #  # ]:          0 :         if (start < root->start)
     207                 :            :                 return root;
     208         [ #  # ]:          0 :         if (end > root->end)
     209                 :            :                 return root;
     210                 :          0 :         p = &root->child;
     211                 :            :         for (;;) {
     212                 :          0 :                 tmp = *p;
     213 [ #  # ][ #  # ]:          0 :                 if (!tmp || tmp->start > end) {
     214                 :          0 :                         new->sibling = tmp;
     215                 :          0 :                         *p = new;
     216                 :          0 :                         new->parent = root;
     217                 :          0 :                         return NULL;
     218                 :            :                 }
     219                 :          0 :                 p = &tmp->sibling;
     220         [ #  # ]:          0 :                 if (tmp->end < start)
     221                 :          0 :                         continue;
     222                 :            :                 return tmp;
     223                 :          0 :         }
     224                 :            : }
     225                 :            : 
     226                 :            : static int __release_resource(struct resource *old)
     227                 :            : {
     228                 :            :         struct resource *tmp, **p;
     229                 :            : 
     230                 :          0 :         p = &old->parent->child;
     231                 :            :         for (;;) {
     232                 :          0 :                 tmp = *p;
     233 [ #  # ][ #  # ]:          0 :                 if (!tmp)
     234                 :            :                         break;
     235 [ #  # ][ #  # ]:          0 :                 if (tmp == old) {
     236                 :          0 :                         *p = tmp->sibling;
     237                 :          0 :                         old->parent = NULL;
     238                 :            :                         return 0;
     239                 :            :                 }
     240                 :          0 :                 p = &tmp->sibling;
     241                 :            :         }
     242                 :            :         return -EINVAL;
     243                 :            : }
     244                 :            : 
     245                 :          0 : static void __release_child_resources(struct resource *r)
     246                 :            : {
     247                 :          0 :         struct resource *tmp, *p;
     248                 :            :         resource_size_t size;
     249                 :            : 
     250                 :          0 :         p = r->child;
     251                 :          0 :         r->child = NULL;
     252         [ #  # ]:          0 :         while (p) {
     253                 :            :                 tmp = p;
     254                 :          0 :                 p = p->sibling;
     255                 :            : 
     256                 :          0 :                 tmp->parent = NULL;
     257                 :          0 :                 tmp->sibling = NULL;
     258                 :          0 :                 __release_child_resources(tmp);
     259                 :            : 
     260                 :          0 :                 printk(KERN_DEBUG "release child resource %pR\n", tmp);
     261                 :            :                 /* need to restore size, and keep flags */
     262                 :            :                 size = resource_size(tmp);
     263                 :          0 :                 tmp->start = 0;
     264                 :          0 :                 tmp->end = size - 1;
     265                 :            :         }
     266                 :          0 : }
     267                 :            : 
     268                 :          0 : void release_child_resources(struct resource *r)
     269                 :            : {
     270                 :          0 :         write_lock(&resource_lock);
     271                 :          0 :         __release_child_resources(r);
     272                 :            :         write_unlock(&resource_lock);
     273                 :          0 : }
     274                 :            : 
     275                 :            : /**
     276                 :            :  * request_resource_conflict - request and reserve an I/O or memory resource
     277                 :            :  * @root: root resource descriptor
     278                 :            :  * @new: resource descriptor desired by caller
     279                 :            :  *
     280                 :            :  * Returns 0 for success, conflict resource on error.
     281                 :            :  */
     282                 :          0 : struct resource *request_resource_conflict(struct resource *root, struct resource *new)
     283                 :            : {
     284                 :            :         struct resource *conflict;
     285                 :            : 
     286                 :          0 :         write_lock(&resource_lock);
     287                 :          0 :         conflict = __request_resource(root, new);
     288                 :            :         write_unlock(&resource_lock);
     289                 :          0 :         return conflict;
     290                 :            : }
     291                 :            : 
     292                 :            : /**
     293                 :            :  * request_resource - request and reserve an I/O or memory resource
     294                 :            :  * @root: root resource descriptor
     295                 :            :  * @new: resource descriptor desired by caller
     296                 :            :  *
     297                 :            :  * Returns 0 for success, negative error code on error.
     298                 :            :  */
     299                 :          0 : int request_resource(struct resource *root, struct resource *new)
     300                 :            : {
     301                 :            :         struct resource *conflict;
     302                 :            : 
     303                 :          0 :         conflict = request_resource_conflict(root, new);
     304 [ #  # ][ #  # ]:          0 :         return conflict ? -EBUSY : 0;
     305                 :            : }
     306                 :            : 
     307                 :            : EXPORT_SYMBOL(request_resource);
     308                 :            : 
     309                 :            : /**
     310                 :            :  * release_resource - release a previously reserved resource
     311                 :            :  * @old: resource pointer
     312                 :            :  */
     313                 :          0 : int release_resource(struct resource *old)
     314                 :            : {
     315                 :            :         int retval;
     316                 :            : 
     317                 :          0 :         write_lock(&resource_lock);
     318                 :            :         retval = __release_resource(old);
     319                 :            :         write_unlock(&resource_lock);
     320                 :          0 :         return retval;
     321                 :            : }
     322                 :            : 
     323                 :            : EXPORT_SYMBOL(release_resource);
     324                 :            : 
     325                 :            : #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
     326                 :            : /*
     327                 :            :  * Finds the lowest memory reosurce exists within [res->start.res->end)
     328                 :            :  * the caller must specify res->start, res->end, res->flags and "name".
     329                 :            :  * If found, returns 0, res is overwritten, if not found, returns -1.
     330                 :            :  */
     331                 :          0 : static int find_next_system_ram(struct resource *res, char *name)
     332                 :            : {
     333                 :            :         resource_size_t start, end;
     334                 :            :         struct resource *p;
     335                 :            : 
     336         [ #  # ]:          0 :         BUG_ON(!res);
     337                 :            : 
     338                 :          0 :         start = res->start;
     339                 :          0 :         end = res->end;
     340         [ #  # ]:          0 :         BUG_ON(start >= end);
     341                 :            : 
     342                 :          0 :         read_lock(&resource_lock);
     343         [ #  # ]:          0 :         for (p = iomem_resource.child; p ; p = p->sibling) {
     344                 :            :                 /* system ram is just marked as IORESOURCE_MEM */
     345         [ #  # ]:          0 :                 if (p->flags != res->flags)
     346                 :          0 :                         continue;
     347 [ #  # ][ #  # ]:          0 :                 if (name && strcmp(p->name, name))
     348                 :          0 :                         continue;
     349         [ #  # ]:          0 :                 if (p->start > end) {
     350                 :            :                         p = NULL;
     351                 :            :                         break;
     352                 :            :                 }
     353 [ #  # ][ #  # ]:          0 :                 if ((p->end >= start) && (p->start < end))
     354                 :            :                         break;
     355                 :            :         }
     356                 :            :         read_unlock(&resource_lock);
     357         [ #  # ]:          0 :         if (!p)
     358                 :            :                 return -1;
     359                 :            :         /* copy data */
     360         [ #  # ]:          0 :         if (res->start < p->start)
     361                 :          0 :                 res->start = p->start;
     362         [ #  # ]:          0 :         if (res->end > p->end)
     363                 :          0 :                 res->end = p->end;
     364                 :            :         return 0;
     365                 :            : }
     366                 :            : 
     367                 :            : /*
     368                 :            :  * This function calls callback against all memory range of "System RAM"
     369                 :            :  * which are marked as IORESOURCE_MEM and IORESOUCE_BUSY.
     370                 :            :  * Now, this function is only for "System RAM".
     371                 :            :  */
     372                 :          0 : int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
     373                 :            :                 void *arg, int (*func)(unsigned long, unsigned long, void *))
     374                 :            : {
     375                 :            :         struct resource res;
     376                 :            :         unsigned long pfn, end_pfn;
     377                 :            :         u64 orig_end;
     378                 :            :         int ret = -1;
     379                 :            : 
     380                 :          0 :         res.start = (u64) start_pfn << PAGE_SHIFT;
     381                 :          0 :         res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
     382                 :          0 :         res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
     383                 :            :         orig_end = res.end;
     384   [ #  #  #  # ]:          0 :         while ((res.start < res.end) &&
     385                 :          0 :                 (find_next_system_ram(&res, "System RAM") >= 0)) {
     386                 :          0 :                 pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
     387                 :          0 :                 end_pfn = (res.end + 1) >> PAGE_SHIFT;
     388         [ #  # ]:          0 :                 if (end_pfn > pfn)
     389                 :          0 :                         ret = (*func)(pfn, end_pfn - pfn, arg);
     390         [ #  # ]:          0 :                 if (ret)
     391                 :            :                         break;
     392                 :          0 :                 res.start = res.end + 1;
     393                 :          0 :                 res.end = orig_end;
     394                 :            :         }
     395                 :          0 :         return ret;
     396                 :            : }
     397                 :            : 
     398                 :            : #endif
     399                 :            : 
     400                 :          0 : static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg)
     401                 :            : {
     402                 :          0 :         return 1;
     403                 :            : }
     404                 :            : /*
     405                 :            :  * This generic page_is_ram() returns true if specified address is
     406                 :            :  * registered as "System RAM" in iomem_resource list.
     407                 :            :  */
     408                 :          0 : int __weak page_is_ram(unsigned long pfn)
     409                 :            : {
     410                 :          0 :         return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
     411                 :            : }
     412                 :            : EXPORT_SYMBOL_GPL(page_is_ram);
     413                 :            : 
     414                 :          0 : void __weak arch_remove_reservations(struct resource *avail)
     415                 :            : {
     416                 :          0 : }
     417                 :            : 
     418                 :          0 : static resource_size_t simple_align_resource(void *data,
     419                 :            :                                              const struct resource *avail,
     420                 :            :                                              resource_size_t size,
     421                 :            :                                              resource_size_t align)
     422                 :            : {
     423                 :          0 :         return avail->start;
     424                 :            : }
     425                 :            : 
     426                 :            : static void resource_clip(struct resource *res, resource_size_t min,
     427                 :            :                           resource_size_t max)
     428                 :            : {
     429         [ #  # ]:          0 :         if (res->start < min)
     430                 :          0 :                 res->start = min;
     431         [ #  # ]:          0 :         if (res->end > max)
     432                 :          0 :                 res->end = max;
     433                 :            : }
     434                 :            : 
     435                 :            : static bool resource_contains(struct resource *res1, struct resource *res2)
     436                 :            : {
     437 [ #  # ][ #  # ]:          0 :         return res1->start <= res2->start && res1->end >= res2->end;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     438                 :            : }
     439                 :            : 
     440                 :            : /*
     441                 :            :  * Find empty slot in the resource tree with the given range and
     442                 :            :  * alignment constraints
     443                 :            :  */
     444                 :          0 : static int __find_resource(struct resource *root, struct resource *old,
     445                 :            :                          struct resource *new,
     446                 :            :                          resource_size_t  size,
     447                 :            :                          struct resource_constraint *constraint)
     448                 :            : {
     449                 :          0 :         struct resource *this = root->child;
     450                 :          0 :         struct resource tmp = *new, avail, alloc;
     451                 :            : 
     452                 :          0 :         tmp.start = root->start;
     453                 :            :         /*
     454                 :            :          * Skip past an allocated resource that starts at 0, since the assignment
     455                 :            :          * of this->start - 1 to tmp->end below would cause an underflow.
     456                 :            :          */
     457 [ #  # ][ #  # ]:          0 :         if (this && this->start == root->start) {
     458         [ #  # ]:          0 :                 tmp.start = (this == old) ? old->start : this->end + 1;
     459                 :          0 :                 this = this->sibling;
     460                 :            :         }
     461                 :            :         for(;;) {
     462         [ #  # ]:          0 :                 if (this)
     463         [ #  # ]:          0 :                         tmp.end = (this == old) ?  this->end : this->start - 1;
     464                 :            :                 else
     465                 :          0 :                         tmp.end = root->end;
     466                 :            : 
     467         [ #  # ]:          0 :                 if (tmp.end < tmp.start)
     468                 :            :                         goto next;
     469                 :            : 
     470                 :          0 :                 resource_clip(&tmp, constraint->min, constraint->max);
     471                 :          0 :                 arch_remove_reservations(&tmp);
     472                 :            : 
     473                 :            :                 /* Check for overflow after ALIGN() */
     474                 :          0 :                 avail = *new;
     475                 :          0 :                 avail.start = ALIGN(tmp.start, constraint->align);
     476                 :          0 :                 avail.end = tmp.end;
     477         [ #  # ]:          0 :                 if (avail.start >= tmp.start) {
     478                 :          0 :                         alloc.start = constraint->alignf(constraint->alignf_data, &avail,
     479                 :            :                                         size, constraint->align);
     480                 :          0 :                         alloc.end = alloc.start + size - 1;
     481         [ #  # ]:          0 :                         if (resource_contains(&avail, &alloc)) {
     482                 :          0 :                                 new->start = alloc.start;
     483                 :          0 :                                 new->end = alloc.end;
     484                 :          0 :                                 return 0;
     485                 :            :                         }
     486                 :            :                 }
     487                 :            : 
     488 [ #  # ][ #  # ]:          0 : next:           if (!this || this->end == root->end)
     489                 :            :                         break;
     490                 :            : 
     491         [ #  # ]:          0 :                 if (this != old)
     492                 :          0 :                         tmp.start = this->end + 1;
     493                 :          0 :                 this = this->sibling;
     494                 :          0 :         }
     495                 :            :         return -EBUSY;
     496                 :            : }
     497                 :            : 
     498                 :            : /*
     499                 :            :  * Find empty slot in the resource tree given range and alignment.
     500                 :            :  */
     501                 :            : static int find_resource(struct resource *root, struct resource *new,
     502                 :            :                         resource_size_t size,
     503                 :            :                         struct resource_constraint  *constraint)
     504                 :            : {
     505                 :          0 :         return  __find_resource(root, NULL, new, size, constraint);
     506                 :            : }
     507                 :            : 
     508                 :            : /**
     509                 :            :  * reallocate_resource - allocate a slot in the resource tree given range & alignment.
     510                 :            :  *      The resource will be relocated if the new size cannot be reallocated in the
     511                 :            :  *      current location.
     512                 :            :  *
     513                 :            :  * @root: root resource descriptor
     514                 :            :  * @old:  resource descriptor desired by caller
     515                 :            :  * @newsize: new size of the resource descriptor
     516                 :            :  * @constraint: the size and alignment constraints to be met.
     517                 :            :  */
     518                 :          0 : int reallocate_resource(struct resource *root, struct resource *old,
     519                 :            :                         resource_size_t newsize,
     520                 :            :                         struct resource_constraint  *constraint)
     521                 :            : {
     522                 :            :         int err=0;
     523                 :          0 :         struct resource new = *old;
     524                 :            :         struct resource *conflict;
     525                 :            : 
     526                 :          0 :         write_lock(&resource_lock);
     527                 :            : 
     528         [ #  # ]:          0 :         if ((err = __find_resource(root, old, &new, newsize, constraint)))
     529                 :            :                 goto out;
     530                 :            : 
     531         [ #  # ]:          0 :         if (resource_contains(&new, old)) {
     532                 :          0 :                 old->start = new.start;
     533                 :          0 :                 old->end = new.end;
     534                 :          0 :                 goto out;
     535                 :            :         }
     536                 :            : 
     537         [ #  # ]:          0 :         if (old->child) {
     538                 :            :                 err = -EBUSY;
     539                 :            :                 goto out;
     540                 :            :         }
     541                 :            : 
     542         [ #  # ]:          0 :         if (resource_contains(old, &new)) {
     543                 :          0 :                 old->start = new.start;
     544                 :          0 :                 old->end = new.end;
     545                 :            :         } else {
     546                 :            :                 __release_resource(old);
     547                 :          0 :                 *old = new;
     548                 :          0 :                 conflict = __request_resource(root, old);
     549         [ #  # ]:          0 :                 BUG_ON(conflict);
     550                 :            :         }
     551                 :            : out:
     552                 :            :         write_unlock(&resource_lock);
     553                 :          0 :         return err;
     554                 :            : }
     555                 :            : 
     556                 :            : 
     557                 :            : /**
     558                 :            :  * allocate_resource - allocate empty slot in the resource tree given range & alignment.
     559                 :            :  *      The resource will be reallocated with a new size if it was already allocated
     560                 :            :  * @root: root resource descriptor
     561                 :            :  * @new: resource descriptor desired by caller
     562                 :            :  * @size: requested resource region size
     563                 :            :  * @min: minimum boundary to allocate
     564                 :            :  * @max: maximum boundary to allocate
     565                 :            :  * @align: alignment requested, in bytes
     566                 :            :  * @alignf: alignment function, optional, called if not NULL
     567                 :            :  * @alignf_data: arbitrary data to pass to the @alignf function
     568                 :            :  */
     569                 :          0 : int allocate_resource(struct resource *root, struct resource *new,
     570                 :            :                       resource_size_t size, resource_size_t min,
     571                 :            :                       resource_size_t max, resource_size_t align,
     572                 :            :                       resource_size_t (*alignf)(void *,
     573                 :            :                                                 const struct resource *,
     574                 :            :                                                 resource_size_t,
     575                 :            :                                                 resource_size_t),
     576                 :            :                       void *alignf_data)
     577                 :            : {
     578                 :            :         int err;
     579                 :            :         struct resource_constraint constraint;
     580                 :            : 
     581         [ #  # ]:          0 :         if (!alignf)
     582                 :            :                 alignf = simple_align_resource;
     583                 :            : 
     584                 :          0 :         constraint.min = min;
     585                 :          0 :         constraint.max = max;
     586                 :          0 :         constraint.align = align;
     587                 :          0 :         constraint.alignf = alignf;
     588                 :          0 :         constraint.alignf_data = alignf_data;
     589                 :            : 
     590         [ #  # ]:          0 :         if ( new->parent ) {
     591                 :            :                 /* resource is already allocated, try reallocating with
     592                 :            :                    the new constraints */
     593                 :          0 :                 return reallocate_resource(root, new, size, &constraint);
     594                 :            :         }
     595                 :            : 
     596                 :          0 :         write_lock(&resource_lock);
     597                 :            :         err = find_resource(root, new, size, &constraint);
     598 [ #  # ][ #  # ]:          0 :         if (err >= 0 && __request_resource(root, new))
     599                 :            :                 err = -EBUSY;
     600                 :            :         write_unlock(&resource_lock);
     601                 :          0 :         return err;
     602                 :            : }
     603                 :            : 
     604                 :            : EXPORT_SYMBOL(allocate_resource);
     605                 :            : 
     606                 :            : /**
     607                 :            :  * lookup_resource - find an existing resource by a resource start address
     608                 :            :  * @root: root resource descriptor
     609                 :            :  * @start: resource start address
     610                 :            :  *
     611                 :            :  * Returns a pointer to the resource if found, NULL otherwise
     612                 :            :  */
     613                 :          0 : struct resource *lookup_resource(struct resource *root, resource_size_t start)
     614                 :            : {
     615                 :            :         struct resource *res;
     616                 :            : 
     617                 :          0 :         read_lock(&resource_lock);
     618         [ #  # ]:          0 :         for (res = root->child; res; res = res->sibling) {
     619         [ #  # ]:          0 :                 if (res->start == start)
     620                 :            :                         break;
     621                 :            :         }
     622                 :            :         read_unlock(&resource_lock);
     623                 :            : 
     624                 :          0 :         return res;
     625                 :            : }
     626                 :            : 
     627                 :            : /*
     628                 :            :  * Insert a resource into the resource tree. If successful, return NULL,
     629                 :            :  * otherwise return the conflicting resource (compare to __request_resource())
     630                 :            :  */
     631                 :          0 : static struct resource * __insert_resource(struct resource *parent, struct resource *new)
     632                 :            : {
     633                 :            :         struct resource *first, *next;
     634                 :            : 
     635                 :            :         for (;; parent = first) {
     636                 :          0 :                 first = __request_resource(parent, new);
     637         [ #  # ]:          0 :                 if (!first)
     638                 :            :                         return first;
     639                 :            : 
     640         [ #  # ]:          0 :                 if (first == parent)
     641                 :            :                         return first;
     642 [ #  # ][ #  # ]:          0 :                 if (WARN_ON(first == new))      /* duplicated insertion */
     643                 :            :                         return first;
     644                 :            : 
     645 [ #  # ][ #  # ]:          0 :                 if ((first->start > new->start) || (first->end < new->end))
     646                 :            :                         break;
     647 [ #  # ][ #  # ]:          0 :                 if ((first->start == new->start) && (first->end == new->end))
     648                 :            :                         break;
     649                 :            :         }
     650                 :            : 
     651                 :            :         for (next = first; ; next = next->sibling) {
     652                 :            :                 /* Partial overlap? Bad, and unfixable */
     653 [ #  # ][ #  # ]:          0 :                 if (next->start < new->start || next->end > new->end)
     654                 :            :                         return next;
     655         [ #  # ]:          0 :                 if (!next->sibling)
     656                 :            :                         break;
     657         [ #  # ]:          0 :                 if (next->sibling->start > new->end)
     658                 :            :                         break;
     659                 :            :         }
     660                 :            : 
     661                 :          0 :         new->parent = parent;
     662                 :          0 :         new->sibling = next->sibling;
     663                 :          0 :         new->child = first;
     664                 :            : 
     665                 :          0 :         next->sibling = NULL;
     666         [ #  # ]:          0 :         for (next = first; next; next = next->sibling)
     667                 :          0 :                 next->parent = new;
     668                 :            : 
     669         [ #  # ]:          0 :         if (parent->child == first) {
     670                 :          0 :                 parent->child = new;
     671                 :            :         } else {
     672                 :            :                 next = parent->child;
     673         [ #  # ]:          0 :                 while (next->sibling != first)
     674                 :            :                         next = next->sibling;
     675                 :          0 :                 next->sibling = new;
     676                 :            :         }
     677                 :            :         return NULL;
     678                 :            : }
     679                 :            : 
     680                 :            : /**
     681                 :            :  * insert_resource_conflict - Inserts resource in the resource tree
     682                 :            :  * @parent: parent of the new resource
     683                 :            :  * @new: new resource to insert
     684                 :            :  *
     685                 :            :  * Returns 0 on success, conflict resource if the resource can't be inserted.
     686                 :            :  *
     687                 :            :  * This function is equivalent to request_resource_conflict when no conflict
     688                 :            :  * happens. If a conflict happens, and the conflicting resources
     689                 :            :  * entirely fit within the range of the new resource, then the new
     690                 :            :  * resource is inserted and the conflicting resources become children of
     691                 :            :  * the new resource.
     692                 :            :  */
     693                 :          0 : struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
     694                 :            : {
     695                 :            :         struct resource *conflict;
     696                 :            : 
     697                 :          0 :         write_lock(&resource_lock);
     698                 :          0 :         conflict = __insert_resource(parent, new);
     699                 :            :         write_unlock(&resource_lock);
     700                 :          0 :         return conflict;
     701                 :            : }
     702                 :            : 
     703                 :            : /**
     704                 :            :  * insert_resource - Inserts a resource in the resource tree
     705                 :            :  * @parent: parent of the new resource
     706                 :            :  * @new: new resource to insert
     707                 :            :  *
     708                 :            :  * Returns 0 on success, -EBUSY if the resource can't be inserted.
     709                 :            :  */
     710                 :          0 : int insert_resource(struct resource *parent, struct resource *new)
     711                 :            : {
     712                 :            :         struct resource *conflict;
     713                 :            : 
     714                 :          0 :         conflict = insert_resource_conflict(parent, new);
     715         [ #  # ]:          0 :         return conflict ? -EBUSY : 0;
     716                 :            : }
     717                 :            : 
     718                 :            : /**
     719                 :            :  * insert_resource_expand_to_fit - Insert a resource into the resource tree
     720                 :            :  * @root: root resource descriptor
     721                 :            :  * @new: new resource to insert
     722                 :            :  *
     723                 :            :  * Insert a resource into the resource tree, possibly expanding it in order
     724                 :            :  * to make it encompass any conflicting resources.
     725                 :            :  */
     726                 :          0 : void insert_resource_expand_to_fit(struct resource *root, struct resource *new)
     727                 :            : {
     728         [ #  # ]:          0 :         if (new->parent)
     729                 :          0 :                 return;
     730                 :            : 
     731                 :          0 :         write_lock(&resource_lock);
     732                 :            :         for (;;) {
     733                 :            :                 struct resource *conflict;
     734                 :            : 
     735                 :          0 :                 conflict = __insert_resource(root, new);
     736         [ #  # ]:          0 :                 if (!conflict)
     737                 :            :                         break;
     738         [ #  # ]:          0 :                 if (conflict == root)
     739                 :            :                         break;
     740                 :            : 
     741                 :            :                 /* Ok, expand resource to cover the conflict, then try again .. */
     742         [ #  # ]:          0 :                 if (conflict->start < new->start)
     743                 :          0 :                         new->start = conflict->start;
     744         [ #  # ]:          0 :                 if (conflict->end > new->end)
     745                 :          0 :                         new->end = conflict->end;
     746                 :            : 
     747                 :          0 :                 printk("Expanded resource %s due to conflict with %s\n", new->name, conflict->name);
     748                 :          0 :         }
     749                 :            :         write_unlock(&resource_lock);
     750                 :            : }
     751                 :            : 
     752                 :          0 : static int __adjust_resource(struct resource *res, resource_size_t start,
     753                 :            :                                 resource_size_t size)
     754                 :            : {
     755                 :          0 :         struct resource *tmp, *parent = res->parent;
     756                 :          0 :         resource_size_t end = start + size - 1;
     757                 :            :         int result = -EBUSY;
     758                 :            : 
     759         [ #  # ]:          0 :         if (!parent)
     760                 :            :                 goto skip;
     761                 :            : 
     762 [ #  # ][ #  # ]:          0 :         if ((start < parent->start) || (end > parent->end))
     763                 :            :                 goto out;
     764                 :            : 
     765 [ #  # ][ #  # ]:          0 :         if (res->sibling && (res->sibling->start <= end))
     766                 :            :                 goto out;
     767                 :            : 
     768                 :          0 :         tmp = parent->child;
     769         [ #  # ]:          0 :         if (tmp != res) {
     770         [ #  # ]:          0 :                 while (tmp->sibling != res)
     771                 :            :                         tmp = tmp->sibling;
     772         [ #  # ]:          0 :                 if (start <= tmp->end)
     773                 :            :                         goto out;
     774                 :            :         }
     775                 :            : 
     776                 :            : skip:
     777         [ #  # ]:          0 :         for (tmp = res->child; tmp; tmp = tmp->sibling)
     778 [ #  # ][ #  # ]:          0 :                 if ((tmp->start < start) || (tmp->end > end))
     779                 :            :                         goto out;
     780                 :            : 
     781                 :          0 :         res->start = start;
     782                 :          0 :         res->end = end;
     783                 :            :         result = 0;
     784                 :            : 
     785                 :            :  out:
     786                 :          0 :         return result;
     787                 :            : }
     788                 :            : 
     789                 :            : /**
     790                 :            :  * adjust_resource - modify a resource's start and size
     791                 :            :  * @res: resource to modify
     792                 :            :  * @start: new start value
     793                 :            :  * @size: new size
     794                 :            :  *
     795                 :            :  * Given an existing resource, change its start and size to match the
     796                 :            :  * arguments.  Returns 0 on success, -EBUSY if it can't fit.
     797                 :            :  * Existing children of the resource are assumed to be immutable.
     798                 :            :  */
     799                 :          0 : int adjust_resource(struct resource *res, resource_size_t start,
     800                 :            :                         resource_size_t size)
     801                 :            : {
     802                 :            :         int result;
     803                 :            : 
     804                 :          0 :         write_lock(&resource_lock);
     805                 :          0 :         result = __adjust_resource(res, start, size);
     806                 :            :         write_unlock(&resource_lock);
     807                 :          0 :         return result;
     808                 :            : }
     809                 :            : EXPORT_SYMBOL(adjust_resource);
     810                 :            : 
     811                 :          0 : static void __init __reserve_region_with_split(struct resource *root,
     812                 :            :                 resource_size_t start, resource_size_t end,
     813                 :            :                 const char *name)
     814                 :            : {
     815                 :            :         struct resource *parent = root;
     816                 :            :         struct resource *conflict;
     817                 :          0 :         struct resource *res = alloc_resource(GFP_ATOMIC);
     818                 :            :         struct resource *next_res = NULL;
     819                 :            : 
     820         [ #  # ]:          0 :         if (!res)
     821                 :          0 :                 return;
     822                 :            : 
     823                 :          0 :         res->name = name;
     824                 :          0 :         res->start = start;
     825                 :          0 :         res->end = end;
     826                 :          0 :         res->flags = IORESOURCE_BUSY;
     827                 :            : 
     828                 :            :         while (1) {
     829                 :            : 
     830                 :          0 :                 conflict = __request_resource(parent, res);
     831         [ #  # ]:          0 :                 if (!conflict) {
     832         [ #  # ]:          0 :                         if (!next_res)
     833                 :            :                                 break;
     834                 :            :                         res = next_res;
     835                 :            :                         next_res = NULL;
     836                 :          0 :                         continue;
     837                 :            :                 }
     838                 :            : 
     839                 :            :                 /* conflict covered whole area */
     840 [ #  # ][ #  # ]:          0 :                 if (conflict->start <= res->start &&
     841                 :          0 :                                 conflict->end >= res->end) {
     842                 :          0 :                         free_resource(res);
     843         [ #  # ]:          0 :                         WARN_ON(next_res);
     844                 :            :                         break;
     845                 :            :                 }
     846                 :            : 
     847                 :            :                 /* failed, split and try again */
     848         [ #  # ]:          0 :                 if (conflict->start > res->start) {
     849                 :          0 :                         end = res->end;
     850                 :          0 :                         res->end = conflict->start - 1;
     851         [ #  # ]:          0 :                         if (conflict->end < end) {
     852                 :          0 :                                 next_res = alloc_resource(GFP_ATOMIC);
     853         [ #  # ]:          0 :                                 if (!next_res) {
     854                 :          0 :                                         free_resource(res);
     855                 :          0 :                                         break;
     856                 :            :                                 }
     857                 :          0 :                                 next_res->name = name;
     858                 :          0 :                                 next_res->start = conflict->end + 1;
     859                 :          0 :                                 next_res->end = end;
     860                 :          0 :                                 next_res->flags = IORESOURCE_BUSY;
     861                 :            :                         }
     862                 :            :                 } else {
     863                 :          0 :                         res->start = conflict->end + 1;
     864                 :            :                 }
     865                 :            :         }
     866                 :            : 
     867                 :            : }
     868                 :            : 
     869                 :          0 : void __init reserve_region_with_split(struct resource *root,
     870                 :            :                 resource_size_t start, resource_size_t end,
     871                 :            :                 const char *name)
     872                 :            : {
     873                 :            :         int abort = 0;
     874                 :            : 
     875                 :          0 :         write_lock(&resource_lock);
     876 [ #  # ][ #  # ]:          0 :         if (root->start > start || root->end < end) {
     877                 :          0 :                 pr_err("requested range [0x%llx-0x%llx] not in root %pr\n",
     878                 :            :                        (unsigned long long)start, (unsigned long long)end,
     879                 :            :                        root);
     880 [ #  # ][ #  # ]:          0 :                 if (start > root->end || end < root->start)
     881                 :            :                         abort = 1;
     882                 :            :                 else {
     883         [ #  # ]:          0 :                         if (end > root->end)
     884                 :            :                                 end = root->end;
     885         [ #  # ]:          0 :                         if (start < root->start)
     886                 :            :                                 start = root->start;
     887                 :          0 :                         pr_err("fixing request to [0x%llx-0x%llx]\n",
     888                 :            :                                (unsigned long long)start,
     889                 :            :                                (unsigned long long)end);
     890                 :            :                 }
     891                 :          0 :                 dump_stack();
     892                 :            :         }
     893         [ #  # ]:          0 :         if (!abort)
     894                 :          0 :                 __reserve_region_with_split(root, start, end, name);
     895                 :            :         write_unlock(&resource_lock);
     896                 :          0 : }
     897                 :            : 
     898                 :            : /**
     899                 :            :  * resource_alignment - calculate resource's alignment
     900                 :            :  * @res: resource pointer
     901                 :            :  *
     902                 :            :  * Returns alignment on success, 0 (invalid alignment) on failure.
     903                 :            :  */
     904                 :          0 : resource_size_t resource_alignment(struct resource *res)
     905                 :            : {
     906      [ #  #  # ]:          0 :         switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) {
     907                 :            :         case IORESOURCE_SIZEALIGN:
     908                 :          0 :                 return resource_size(res);
     909                 :            :         case IORESOURCE_STARTALIGN:
     910                 :          0 :                 return res->start;
     911                 :            :         default:
     912                 :            :                 return 0;
     913                 :            :         }
     914                 :            : }
     915                 :            : 
     916                 :            : /*
     917                 :            :  * This is compatibility stuff for IO resources.
     918                 :            :  *
     919                 :            :  * Note how this, unlike the above, knows about
     920                 :            :  * the IO flag meanings (busy etc).
     921                 :            :  *
     922                 :            :  * request_region creates a new busy region.
     923                 :            :  *
     924                 :            :  * check_region returns non-zero if the area is already busy.
     925                 :            :  *
     926                 :            :  * release_region releases a matching busy region.
     927                 :            :  */
     928                 :            : 
     929                 :            : static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
     930                 :            : 
     931                 :            : /**
     932                 :            :  * __request_region - create a new busy resource region
     933                 :            :  * @parent: parent resource descriptor
     934                 :            :  * @start: resource start address
     935                 :            :  * @n: resource region size
     936                 :            :  * @name: reserving caller's ID string
     937                 :            :  * @flags: IO resource flags
     938                 :            :  */
     939                 :          0 : struct resource * __request_region(struct resource *parent,
     940                 :            :                                    resource_size_t start, resource_size_t n,
     941                 :            :                                    const char *name, int flags)
     942                 :            : {
     943                 :          0 :         DECLARE_WAITQUEUE(wait, current);
     944                 :          0 :         struct resource *res = alloc_resource(GFP_KERNEL);
     945                 :            : 
     946         [ #  # ]:          0 :         if (!res)
     947                 :            :                 return NULL;
     948                 :            : 
     949                 :          0 :         res->name = name;
     950                 :          0 :         res->start = start;
     951                 :          0 :         res->end = start + n - 1;
     952                 :          0 :         res->flags = IORESOURCE_BUSY;
     953                 :          0 :         res->flags |= flags;
     954                 :            : 
     955                 :          0 :         write_lock(&resource_lock);
     956                 :            : 
     957                 :            :         for (;;) {
     958                 :            :                 struct resource *conflict;
     959                 :            : 
     960                 :          0 :                 conflict = __request_resource(parent, res);
     961         [ #  # ]:          0 :                 if (!conflict)
     962                 :            :                         break;
     963         [ #  # ]:          0 :                 if (conflict != parent) {
     964                 :            :                         parent = conflict;
     965         [ #  # ]:          0 :                         if (!(conflict->flags & IORESOURCE_BUSY))
     966                 :          0 :                                 continue;
     967                 :            :                 }
     968         [ #  # ]:          0 :                 if (conflict->flags & flags & IORESOURCE_MUXED) {
     969                 :          0 :                         add_wait_queue(&muxed_resource_wait, &wait);
     970                 :            :                         write_unlock(&resource_lock);
     971                 :          0 :                         set_current_state(TASK_UNINTERRUPTIBLE);
     972                 :          0 :                         schedule();
     973                 :          0 :                         remove_wait_queue(&muxed_resource_wait, &wait);
     974                 :          0 :                         write_lock(&resource_lock);
     975                 :          0 :                         continue;
     976                 :            :                 }
     977                 :            :                 /* Uhhuh, that didn't work out.. */
     978                 :          0 :                 free_resource(res);
     979                 :            :                 res = NULL;
     980                 :          0 :                 break;
     981                 :            :         }
     982                 :            :         write_unlock(&resource_lock);
     983                 :          0 :         return res;
     984                 :            : }
     985                 :            : EXPORT_SYMBOL(__request_region);
     986                 :            : 
     987                 :            : /**
     988                 :            :  * __check_region - check if a resource region is busy or free
     989                 :            :  * @parent: parent resource descriptor
     990                 :            :  * @start: resource start address
     991                 :            :  * @n: resource region size
     992                 :            :  *
     993                 :            :  * Returns 0 if the region is free at the moment it is checked,
     994                 :            :  * returns %-EBUSY if the region is busy.
     995                 :            :  *
     996                 :            :  * NOTE:
     997                 :            :  * This function is deprecated because its use is racy.
     998                 :            :  * Even if it returns 0, a subsequent call to request_region()
     999                 :            :  * may fail because another driver etc. just allocated the region.
    1000                 :            :  * Do NOT use it.  It will be removed from the kernel.
    1001                 :            :  */
    1002                 :          0 : int __check_region(struct resource *parent, resource_size_t start,
    1003                 :            :                         resource_size_t n)
    1004                 :            : {
    1005                 :            :         struct resource * res;
    1006                 :            : 
    1007                 :          0 :         res = __request_region(parent, start, n, "check-region", 0);
    1008         [ #  # ]:          0 :         if (!res)
    1009                 :            :                 return -EBUSY;
    1010                 :            : 
    1011                 :          0 :         release_resource(res);
    1012                 :          0 :         free_resource(res);
    1013                 :          0 :         return 0;
    1014                 :            : }
    1015                 :            : EXPORT_SYMBOL(__check_region);
    1016                 :            : 
    1017                 :            : /**
    1018                 :            :  * __release_region - release a previously reserved resource region
    1019                 :            :  * @parent: parent resource descriptor
    1020                 :            :  * @start: resource start address
    1021                 :            :  * @n: resource region size
    1022                 :            :  *
    1023                 :            :  * The described resource region must match a currently busy region.
    1024                 :            :  */
    1025                 :          0 : void __release_region(struct resource *parent, resource_size_t start,
    1026                 :            :                         resource_size_t n)
    1027                 :            : {
    1028                 :            :         struct resource **p;
    1029                 :            :         resource_size_t end;
    1030                 :            : 
    1031                 :          0 :         p = &parent->child;
    1032                 :          0 :         end = start + n - 1;
    1033                 :            : 
    1034                 :          0 :         write_lock(&resource_lock);
    1035                 :            : 
    1036                 :            :         for (;;) {
    1037                 :          0 :                 struct resource *res = *p;
    1038                 :            : 
    1039         [ #  # ]:          0 :                 if (!res)
    1040                 :            :                         break;
    1041 [ #  # ][ #  # ]:          0 :                 if (res->start <= start && res->end >= end) {
    1042         [ #  # ]:          0 :                         if (!(res->flags & IORESOURCE_BUSY)) {
    1043                 :          0 :                                 p = &res->child;
    1044                 :          0 :                                 continue;
    1045                 :            :                         }
    1046 [ #  # ][ #  # ]:          0 :                         if (res->start != start || res->end != end)
    1047                 :            :                                 break;
    1048                 :          0 :                         *p = res->sibling;
    1049                 :            :                         write_unlock(&resource_lock);
    1050         [ #  # ]:          0 :                         if (res->flags & IORESOURCE_MUXED)
    1051                 :          0 :                                 wake_up(&muxed_resource_wait);
    1052                 :          0 :                         free_resource(res);
    1053                 :          0 :                         return;
    1054                 :            :                 }
    1055                 :          0 :                 p = &res->sibling;
    1056                 :            :         }
    1057                 :            : 
    1058                 :            :         write_unlock(&resource_lock);
    1059                 :            : 
    1060                 :          0 :         printk(KERN_WARNING "Trying to free nonexistent resource "
    1061                 :            :                 "<%016llx-%016llx>\n", (unsigned long long)start,
    1062                 :            :                 (unsigned long long)end);
    1063                 :            : }
    1064                 :            : EXPORT_SYMBOL(__release_region);
    1065                 :            : 
    1066                 :            : #ifdef CONFIG_MEMORY_HOTREMOVE
    1067                 :            : /**
    1068                 :            :  * release_mem_region_adjustable - release a previously reserved memory region
    1069                 :            :  * @parent: parent resource descriptor
    1070                 :            :  * @start: resource start address
    1071                 :            :  * @size: resource region size
    1072                 :            :  *
    1073                 :            :  * This interface is intended for memory hot-delete.  The requested region
    1074                 :            :  * is released from a currently busy memory resource.  The requested region
    1075                 :            :  * must either match exactly or fit into a single busy resource entry.  In
    1076                 :            :  * the latter case, the remaining resource is adjusted accordingly.
    1077                 :            :  * Existing children of the busy memory resource must be immutable in the
    1078                 :            :  * request.
    1079                 :            :  *
    1080                 :            :  * Note:
    1081                 :            :  * - Additional release conditions, such as overlapping region, can be
    1082                 :            :  *   supported after they are confirmed as valid cases.
    1083                 :            :  * - When a busy memory resource gets split into two entries, the code
    1084                 :            :  *   assumes that all children remain in the lower address entry for
    1085                 :            :  *   simplicity.  Enhance this logic when necessary.
    1086                 :            :  */
    1087                 :            : int release_mem_region_adjustable(struct resource *parent,
    1088                 :            :                         resource_size_t start, resource_size_t size)
    1089                 :            : {
    1090                 :            :         struct resource **p;
    1091                 :            :         struct resource *res;
    1092                 :            :         struct resource *new_res;
    1093                 :            :         resource_size_t end;
    1094                 :            :         int ret = -EINVAL;
    1095                 :            : 
    1096                 :            :         end = start + size - 1;
    1097                 :            :         if ((start < parent->start) || (end > parent->end))
    1098                 :            :                 return ret;
    1099                 :            : 
    1100                 :            :         /* The alloc_resource() result gets checked later */
    1101                 :            :         new_res = alloc_resource(GFP_KERNEL);
    1102                 :            : 
    1103                 :            :         p = &parent->child;
    1104                 :            :         write_lock(&resource_lock);
    1105                 :            : 
    1106                 :            :         while ((res = *p)) {
    1107                 :            :                 if (res->start >= end)
    1108                 :            :                         break;
    1109                 :            : 
    1110                 :            :                 /* look for the next resource if it does not fit into */
    1111                 :            :                 if (res->start > start || res->end < end) {
    1112                 :            :                         p = &res->sibling;
    1113                 :            :                         continue;
    1114                 :            :                 }
    1115                 :            : 
    1116                 :            :                 if (!(res->flags & IORESOURCE_MEM))
    1117                 :            :                         break;
    1118                 :            : 
    1119                 :            :                 if (!(res->flags & IORESOURCE_BUSY)) {
    1120                 :            :                         p = &res->child;
    1121                 :            :                         continue;
    1122                 :            :                 }
    1123                 :            : 
    1124                 :            :                 /* found the target resource; let's adjust accordingly */
    1125                 :            :                 if (res->start == start && res->end == end) {
    1126                 :            :                         /* free the whole entry */
    1127                 :            :                         *p = res->sibling;
    1128                 :            :                         free_resource(res);
    1129                 :            :                         ret = 0;
    1130                 :            :                 } else if (res->start == start && res->end != end) {
    1131                 :            :                         /* adjust the start */
    1132                 :            :                         ret = __adjust_resource(res, end + 1,
    1133                 :            :                                                 res->end - end);
    1134                 :            :                 } else if (res->start != start && res->end == end) {
    1135                 :            :                         /* adjust the end */
    1136                 :            :                         ret = __adjust_resource(res, res->start,
    1137                 :            :                                                 start - res->start);
    1138                 :            :                 } else {
    1139                 :            :                         /* split into two entries */
    1140                 :            :                         if (!new_res) {
    1141                 :            :                                 ret = -ENOMEM;
    1142                 :            :                                 break;
    1143                 :            :                         }
    1144                 :            :                         new_res->name = res->name;
    1145                 :            :                         new_res->start = end + 1;
    1146                 :            :                         new_res->end = res->end;
    1147                 :            :                         new_res->flags = res->flags;
    1148                 :            :                         new_res->parent = res->parent;
    1149                 :            :                         new_res->sibling = res->sibling;
    1150                 :            :                         new_res->child = NULL;
    1151                 :            : 
    1152                 :            :                         ret = __adjust_resource(res, res->start,
    1153                 :            :                                                 start - res->start);
    1154                 :            :                         if (ret)
    1155                 :            :                                 break;
    1156                 :            :                         res->sibling = new_res;
    1157                 :            :                         new_res = NULL;
    1158                 :            :                 }
    1159                 :            : 
    1160                 :            :                 break;
    1161                 :            :         }
    1162                 :            : 
    1163                 :            :         write_unlock(&resource_lock);
    1164                 :            :         free_resource(new_res);
    1165                 :            :         return ret;
    1166                 :            : }
    1167                 :            : #endif  /* CONFIG_MEMORY_HOTREMOVE */
    1168                 :            : 
    1169                 :            : /*
    1170                 :            :  * Managed region resource
    1171                 :            :  */
    1172                 :            : struct region_devres {
    1173                 :            :         struct resource *parent;
    1174                 :            :         resource_size_t start;
    1175                 :            :         resource_size_t n;
    1176                 :            : };
    1177                 :            : 
    1178                 :          0 : static void devm_region_release(struct device *dev, void *res)
    1179                 :            : {
    1180                 :            :         struct region_devres *this = res;
    1181                 :            : 
    1182                 :          0 :         __release_region(this->parent, this->start, this->n);
    1183                 :          0 : }
    1184                 :            : 
    1185                 :          0 : static int devm_region_match(struct device *dev, void *res, void *match_data)
    1186                 :            : {
    1187                 :            :         struct region_devres *this = res, *match = match_data;
    1188                 :            : 
    1189         [ #  # ]:          0 :         return this->parent == match->parent &&
    1190 [ #  # ][ #  # ]:          0 :                 this->start == match->start && this->n == match->n;
    1191                 :            : }
    1192                 :            : 
    1193                 :          0 : struct resource * __devm_request_region(struct device *dev,
    1194                 :            :                                 struct resource *parent, resource_size_t start,
    1195                 :            :                                 resource_size_t n, const char *name)
    1196                 :            : {
    1197                 :            :         struct region_devres *dr = NULL;
    1198                 :            :         struct resource *res;
    1199                 :            : 
    1200                 :          0 :         dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
    1201                 :            :                           GFP_KERNEL);
    1202         [ #  # ]:          0 :         if (!dr)
    1203                 :            :                 return NULL;
    1204                 :            : 
    1205                 :          0 :         dr->parent = parent;
    1206                 :          0 :         dr->start = start;
    1207                 :          0 :         dr->n = n;
    1208                 :            : 
    1209                 :          0 :         res = __request_region(parent, start, n, name, 0);
    1210         [ #  # ]:          0 :         if (res)
    1211                 :          0 :                 devres_add(dev, dr);
    1212                 :            :         else
    1213                 :          0 :                 devres_free(dr);
    1214                 :            : 
    1215                 :          0 :         return res;
    1216                 :            : }
    1217                 :            : EXPORT_SYMBOL(__devm_request_region);
    1218                 :            : 
    1219                 :          0 : void __devm_release_region(struct device *dev, struct resource *parent,
    1220                 :            :                            resource_size_t start, resource_size_t n)
    1221                 :            : {
    1222                 :          0 :         struct region_devres match_data = { parent, start, n };
    1223                 :            : 
    1224                 :          0 :         __release_region(parent, start, n);
    1225         [ #  # ]:          0 :         WARN_ON(devres_destroy(dev, devm_region_release, devm_region_match,
    1226                 :            :                                &match_data));
    1227                 :          0 : }
    1228                 :            : EXPORT_SYMBOL(__devm_release_region);
    1229                 :            : 
    1230                 :            : /*
    1231                 :            :  * Called from init/main.c to reserve IO ports.
    1232                 :            :  */
    1233                 :            : #define MAXRESERVE 4
    1234                 :          0 : static int __init reserve_setup(char *str)
    1235                 :            : {
    1236                 :            :         static int reserved;
    1237                 :            :         static struct resource reserve[MAXRESERVE];
    1238                 :            : 
    1239                 :            :         for (;;) {
    1240                 :            :                 unsigned int io_start, io_num;
    1241                 :          0 :                 int x = reserved;
    1242                 :            : 
    1243         [ #  # ]:          0 :                 if (get_option (&str, &io_start) != 2)
    1244                 :            :                         break;
    1245         [ #  # ]:          0 :                 if (get_option (&str, &io_num)   == 0)
    1246                 :            :                         break;
    1247         [ #  # ]:          0 :                 if (x < MAXRESERVE) {
    1248                 :          0 :                         struct resource *res = reserve + x;
    1249                 :          0 :                         res->name = "reserved";
    1250                 :          0 :                         res->start = io_start;
    1251                 :          0 :                         res->end = io_start + io_num - 1;
    1252                 :          0 :                         res->flags = IORESOURCE_BUSY;
    1253                 :          0 :                         res->child = NULL;
    1254 [ #  # ][ #  # ]:          0 :                         if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
    1255                 :          0 :                                 reserved = x+1;
    1256                 :            :                 }
    1257                 :          0 :         }
    1258                 :          0 :         return 1;
    1259                 :            : }
    1260                 :            : 
    1261                 :            : __setup("reserve=", reserve_setup);
    1262                 :            : 
    1263                 :            : /*
    1264                 :            :  * Check if the requested addr and size spans more than any slot in the
    1265                 :            :  * iomem resource tree.
    1266                 :            :  */
    1267                 :          0 : int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
    1268                 :            : {
    1269                 :            :         struct resource *p = &iomem_resource;
    1270                 :            :         int err = 0;
    1271                 :            :         loff_t l;
    1272                 :            : 
    1273                 :          0 :         read_lock(&resource_lock);
    1274         [ #  # ]:          0 :         for (p = p->child; p ; p = r_next(NULL, p, &l)) {
    1275                 :            :                 /*
    1276                 :            :                  * We can probably skip the resources without
    1277                 :            :                  * IORESOURCE_IO attribute?
    1278                 :            :                  */
    1279         [ #  # ]:          0 :                 if (p->start >= addr + size)
    1280                 :          0 :                         continue;
    1281         [ #  # ]:          0 :                 if (p->end < addr)
    1282                 :          0 :                         continue;
    1283 [ #  # ][ #  # ]:          0 :                 if (PFN_DOWN(p->start) <= PFN_DOWN(addr) &&
    1284                 :          0 :                     PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1))
    1285                 :          0 :                         continue;
    1286                 :            :                 /*
    1287                 :            :                  * if a resource is "BUSY", it's not a hardware resource
    1288                 :            :                  * but a driver mapping of such a resource; we don't want
    1289                 :            :                  * to warn for those; some drivers legitimately map only
    1290                 :            :                  * partial hardware resources. (example: vesafb)
    1291                 :            :                  */
    1292         [ #  # ]:          0 :                 if (p->flags & IORESOURCE_BUSY)
    1293                 :          0 :                         continue;
    1294                 :            : 
    1295                 :          0 :                 printk(KERN_WARNING "resource map sanity check conflict: "
    1296                 :            :                        "0x%llx 0x%llx 0x%llx 0x%llx %s\n",
    1297                 :            :                        (unsigned long long)addr,
    1298                 :          0 :                        (unsigned long long)(addr + size - 1),
    1299                 :            :                        (unsigned long long)p->start,
    1300                 :            :                        (unsigned long long)p->end,
    1301                 :            :                        p->name);
    1302                 :            :                 err = -1;
    1303                 :          0 :                 break;
    1304                 :            :         }
    1305                 :            :         read_unlock(&resource_lock);
    1306                 :            : 
    1307                 :          0 :         return err;
    1308                 :            : }
    1309                 :            : 
    1310                 :            : #ifdef CONFIG_STRICT_DEVMEM
    1311                 :            : static int strict_iomem_checks = 1;
    1312                 :            : #else
    1313                 :            : static int strict_iomem_checks;
    1314                 :            : #endif
    1315                 :            : 
    1316                 :            : /*
    1317                 :            :  * check if an address is reserved in the iomem resource tree
    1318                 :            :  * returns 1 if reserved, 0 if not reserved.
    1319                 :            :  */
    1320                 :          0 : int iomem_is_exclusive(u64 addr)
    1321                 :            : {
    1322                 :            :         struct resource *p = &iomem_resource;
    1323                 :            :         int err = 0;
    1324                 :            :         loff_t l;
    1325                 :            :         int size = PAGE_SIZE;
    1326                 :            : 
    1327         [ #  # ]:          0 :         if (!strict_iomem_checks)
    1328                 :            :                 return 0;
    1329                 :            : 
    1330                 :          0 :         addr = addr & PAGE_MASK;
    1331                 :            : 
    1332                 :          0 :         read_lock(&resource_lock);
    1333         [ #  # ]:          0 :         for (p = p->child; p ; p = r_next(NULL, p, &l)) {
    1334                 :            :                 /*
    1335                 :            :                  * We can probably skip the resources without
    1336                 :            :                  * IORESOURCE_IO attribute?
    1337                 :            :                  */
    1338         [ #  # ]:          0 :                 if (p->start >= addr + size)
    1339                 :            :                         break;
    1340         [ #  # ]:          0 :                 if (p->end < addr)
    1341                 :          0 :                         continue;
    1342 [ #  # ][ #  # ]:          0 :                 if (p->flags & IORESOURCE_BUSY &&
    1343                 :          0 :                      p->flags & IORESOURCE_EXCLUSIVE) {
    1344                 :            :                         err = 1;
    1345                 :            :                         break;
    1346                 :            :                 }
    1347                 :            :         }
    1348                 :            :         read_unlock(&resource_lock);
    1349                 :            : 
    1350                 :          0 :         return err;
    1351                 :            : }
    1352                 :            : 
    1353                 :          0 : static int __init strict_iomem(char *str)
    1354                 :            : {
    1355         [ #  # ]:          0 :         if (strstr(str, "relaxed"))
    1356                 :          0 :                 strict_iomem_checks = 0;
    1357         [ #  # ]:          0 :         if (strstr(str, "strict"))
    1358                 :          0 :                 strict_iomem_checks = 1;
    1359                 :          0 :         return 1;
    1360                 :            : }
    1361                 :            : 
    1362                 :            : __setup("iomem=", strict_iomem);

Generated by: LCOV version 1.9