LCOV - code coverage report
Current view: top level - drivers/base - map.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 17 67 25.4 %
Date: 2014-02-18 Functions: 1 4 25.0 %
Branches: 9 43 20.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/drivers/base/map.c
       3                 :            :  *
       4                 :            :  * (C) Copyright Al Viro 2002,2003
       5                 :            :  *      Released under GPL v2.
       6                 :            :  *
       7                 :            :  * NOTE: data structure needs to be changed.  It works, but for large dev_t
       8                 :            :  * it will be too slow.  It is isolated, though, so these changes will be
       9                 :            :  * local to that file.
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <linux/module.h>
      13                 :            : #include <linux/slab.h>
      14                 :            : #include <linux/mutex.h>
      15                 :            : #include <linux/kdev_t.h>
      16                 :            : #include <linux/kobject.h>
      17                 :            : #include <linux/kobj_map.h>
      18                 :            : 
      19                 :            : struct kobj_map {
      20                 :            :         struct probe {
      21                 :            :                 struct probe *next;
      22                 :            :                 dev_t dev;
      23                 :            :                 unsigned long range;
      24                 :            :                 struct module *owner;
      25                 :            :                 kobj_probe_t *get;
      26                 :            :                 int (*lock)(dev_t, void *);
      27                 :            :                 void *data;
      28                 :            :         } *probes[255];
      29                 :            :         struct mutex *lock;
      30                 :            : };
      31                 :            : 
      32                 :          0 : int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
      33                 :            :              struct module *module, kobj_probe_t *probe,
      34                 :            :              int (*lock)(dev_t, void *), void *data)
      35                 :            : {
      36                 :          0 :         unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
      37                 :            :         unsigned index = MAJOR(dev);
      38                 :            :         unsigned i;
      39                 :            :         struct probe *p;
      40                 :            : 
      41         [ #  # ]:          0 :         if (n > 255)
      42                 :            :                 n = 255;
      43                 :            : 
      44                 :          0 :         p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);
      45                 :            : 
      46         [ #  # ]:          0 :         if (p == NULL)
      47                 :            :                 return -ENOMEM;
      48                 :            : 
      49         [ #  # ]:          0 :         for (i = 0; i < n; i++, p++) {
      50                 :          0 :                 p->owner = module;
      51                 :          0 :                 p->get = probe;
      52                 :          0 :                 p->lock = lock;
      53                 :          0 :                 p->dev = dev;
      54                 :          0 :                 p->range = range;
      55                 :          0 :                 p->data = data;
      56                 :            :         }
      57                 :          0 :         mutex_lock(domain->lock);
      58         [ #  # ]:          0 :         for (i = 0, p -= n; i < n; i++, p++, index++) {
      59                 :          0 :                 struct probe **s = &domain->probes[index % 255];
      60 [ #  # ][ #  # ]:          0 :                 while (*s && (*s)->range < range)
      61                 :          0 :                         s = &(*s)->next;
      62                 :          0 :                 p->next = *s;
      63                 :          0 :                 *s = p;
      64                 :            :         }
      65                 :          0 :         mutex_unlock(domain->lock);
      66                 :          0 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :          0 : void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
      70                 :            : {
      71                 :          0 :         unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
      72                 :            :         unsigned index = MAJOR(dev);
      73                 :            :         unsigned i;
      74                 :            :         struct probe *found = NULL;
      75                 :            : 
      76         [ #  # ]:          0 :         if (n > 255)
      77                 :            :                 n = 255;
      78                 :            : 
      79                 :          0 :         mutex_lock(domain->lock);
      80         [ #  # ]:          0 :         for (i = 0; i < n; i++, index++) {
      81                 :            :                 struct probe **s;
      82         [ #  # ]:          0 :                 for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
      83                 :            :                         struct probe *p = *s;
      84 [ #  # ][ #  # ]:          0 :                         if (p->dev == dev && p->range == range) {
      85                 :          0 :                                 *s = p->next;
      86         [ #  # ]:          0 :                                 if (!found)
      87                 :            :                                         found = p;
      88                 :            :                                 break;
      89                 :            :                         }
      90                 :            :                 }
      91                 :            :         }
      92                 :          0 :         mutex_unlock(domain->lock);
      93                 :          0 :         kfree(found);
      94                 :          0 : }
      95                 :            : 
      96                 :        414 : struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
      97                 :            : {
      98                 :            :         struct kobject *kobj;
      99                 :            :         struct probe *p;
     100                 :            :         unsigned long best = ~0UL;
     101                 :            : 
     102                 :            : retry:
     103                 :        414 :         mutex_lock(domain->lock);
     104         [ +  - ]:       1954 :         for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
     105                 :            :                 struct kobject *(*probe)(dev_t, int *, void *);
     106                 :            :                 struct module *owner;
     107                 :            :                 void *data;
     108                 :            : 
     109 [ +  + ][ -  + ]:       1954 :                 if (p->dev > dev || p->dev + p->range - 1 < dev)
     110                 :       1540 :                         continue;
     111            [ + ]:        414 :                 if (p->range - 1 >= best)
     112                 :            :                         break;
     113         [ -  + ]:        414 :                 if (!try_module_get(p->owner))
     114                 :          0 :                         continue;
     115                 :        414 :                 owner = p->owner;
     116                 :        414 :                 data = p->data;
     117                 :        414 :                 probe = p->get;
     118                 :        414 :                 best = p->range - 1;
     119                 :        414 :                 *index = dev - p->dev;
     120 [ +  - ][ -  + ]:        414 :                 if (p->lock && p->lock(dev, data) < 0) {
     121                 :          0 :                         module_put(owner);
     122                 :          0 :                         continue;
     123                 :            :                 }
     124                 :        414 :                 mutex_unlock(domain->lock);
     125                 :        414 :                 kobj = probe(dev, index, data);
     126                 :            :                 /* Currently ->owner protects _only_ ->probe() itself. */
     127                 :        414 :                 module_put(owner);
     128         [ -  + ]:        414 :                 if (kobj)
     129                 :            :                         return kobj;
     130                 :            :                 goto retry;
     131                 :            :         }
     132                 :          0 :         mutex_unlock(domain->lock);
     133                 :          0 :         return NULL;
     134                 :            : }
     135                 :            : 
     136                 :          0 : struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)
     137                 :            : {
     138                 :            :         struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
     139                 :            :         struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
     140                 :            :         int i;
     141                 :            : 
     142         [ #  # ]:          0 :         if ((p == NULL) || (base == NULL)) {
     143                 :          0 :                 kfree(p);
     144                 :          0 :                 kfree(base);
     145                 :          0 :                 return NULL;
     146                 :            :         }
     147                 :            : 
     148                 :          0 :         base->dev = 1;
     149                 :          0 :         base->range = ~0;
     150                 :          0 :         base->get = base_probe;
     151         [ #  # ]:          0 :         for (i = 0; i < 255; i++)
     152                 :          0 :                 p->probes[i] = base;
     153                 :          0 :         p->lock = lock;
     154                 :          0 :         return p;
     155                 :            : }

Generated by: LCOV version 1.9