map.c 添加注释

注释仅代表个人理解,难免有错误之处,仅供参考!

  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[];

 29     struct mutex *lock;

 30 };

 31 

 32 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     /* [cgw]: 计算MAJOR(dev)到MAJOR(dev + range - 1)有几个

 37           * 主设备,由于主设备号都一样,所以这里n = 1

 38           */

 39     unsigned n = MAJOR(dev + range - ) - MAJOR(dev) + ;

 40     /* [cgw]: 以主设备号为索引 */

 41     unsigned index = MAJOR(dev);

 42     unsigned i;

 43     struct probe *p;

 44 

 45     /* [cgw]: 主设备超出255个 */

 46     if (n > )

 47         n = ;

 48     /* [cgw]: 分配n个struct probe内存空间*/

 49     p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);

 50     /* [cgw]: 分配失败*/

 51     if (p == NULL)

 52         return -ENOMEM;

 53     /* [cgw]: 填装n个struct probe,对应n个主设备号

 54           * 

 55           */

 56     for (i = ; i < n; i++, p++) {

 57         p->owner = module;

 58         p->get = probe;

 59         p->lock = lock;

 60         p->dev = dev;

 61         p->range = range;

 62         p->data = data;

 63     }

 64     /* [cgw]: 进入临界区*/

 65     mutex_lock(domain->lock);

 66     /* [cgw]: 这里p -= n是因为,在以上for循环中,p++了n次 */

 67     for (i = , p -= n; i < n; i++, p++, index++) {

 68         /* [cgw]: 根据当前索引,从probes[]中

 69               * 取出一个probe

 70               */

 71         struct probe **s = &domain->probes[index % ];

 72         /* [cgw]: probe是一个链表,每个新加入的节点,

 73           * 按照其range的大小,从小到大排列,即头结点的

 74           * range是最小的

 75           */

 76         while (*s && (*s)->range < range)

 77             /* [cgw]: 继续查找下一个probe,直到其range大于

 78                       * 或等于新加入probe的range为止

 79                   */

 80             s = &(*s)->next;

 81         /* [cgw]: 找到了一个probe,其range大于或等于新加入

 82               * probe的range,把这个新加入的probe下一节点指向

 83               * 这个probe节点

 84               */

 85         p->next = *s;

 86         /* [cgw]: 新加入的节点代替旧的位置 */

 87         *s = p;

 88     }

 89     /* [cgw]: 退出临界区*/

 90     mutex_unlock(domain->lock);

 91     return ;

 92 }

 93 

 94 void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)

 95 {

 96     /* [cgw]: 计算MAJOR(dev)到MAJOR(dev + range - 1)有几个

 97           * 主设备,由于主设备号都一样,所以这里n = 1

 98           */

 99     unsigned n = MAJOR(dev + range - ) - MAJOR(dev) + ;

     /* [cgw]: 以主设备号为索引 */

     unsigned index = MAJOR(dev);

     unsigned i;

     struct probe *found = NULL;

     /* [cgw]: 主设备超出255个 */

     if (n > )

         n = ;

     /* [cgw]: 进入临界区*/

     mutex_lock(domain->lock);

     

     for (i = ; i < n; i++, index++) {

         struct probe **s;

         for (s = &domain->probes[index % ]; *s; s = &(*s)->next) {

             struct probe *p = *s;

             /* [cgw]: 找到这个设备,并且其对应的次设备号个数也匹配 */

             if (p->dev == dev && p->range == range) {

                 /* [cgw]: 这个设备对应的节点,被下一节点取代,即移除

                       * 这个节点

                       */

                 *s = p->next;

                 /* [cgw]: 记录这个节点 */

                 if (!found)

                     found = p;

                 break;

             }

         }

     }

     /* [cgw]: 退出临界区*/

     mutex_unlock(domain->lock);

     /* [cgw]: 释放这个节点对应的内存空间 */

     kfree(found);

 }

 

 struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)

 {

     struct kobject *kobj;

     struct probe *p;

     unsigned long best = ~0UL;

 

 retry:  /* [cgw]: 重试 */

     /* [cgw]: 进入临界区 */

     mutex_lock(domain->lock);

     /* [cgw]: 以主设备号为索引,从probes数组取出一个probe */

     for (p = domain->probes[MAJOR(dev) % ]; p; p = p->next) {

         struct kobject *(*probe)(dev_t, int *, void *);

         struct module *owner;

         void *data;

 

         /* [cgw]: 取出的这个probe对应的设备号大于要查找的设备号

                   * 或 这个probe对应的设备号的最大次设备号小于要查找的设备号

                   * 即不在查找范围内,那么返回,继续取出下一个probe

                   */

         if (p->dev > dev || p->dev + p->range -  < dev)

             continue;

         /* [cgw]: 连续的次设备号个数超过最大范围,出错

           */

         if (p->range -  >= best)

             break;

         /* [cgw]: 模块引用失败???? */

         if (!try_module_get(p->owner))

             continue;

         /* [cgw]: 到此,找到了我们想要的那个probe,接着提取它的值 */

         owner = p->owner;

         data = p->data;

         probe = p->get;

         best = p->range - ;

         /* [cgw]: 计算这个要找的设备的次设备号,相对于找到的probe对应

           * 设备号的次设备号的偏移,因为找到的probe对应设备号的次设备号

           * 是这个设备的次设备号基址

           */

         *index = dev - p->dev;

         /* [cgw]: 未搞明白这个判断的意思 */

         if (p->lock && p->lock(dev, data) < ) {

             /* [cgw]: 放弃模块使用权???? */

             module_put(owner);

             continue;

         }

         /* [cgw]: 退出临界区 */

         mutex_unlock(domain->lock);

         /* [cgw]: 调用probe的实现函数,并返回对应的kobj */

         kobj = probe(dev, index, data);

         /* Currently ->owner protects _only_ ->probe() itself. */

         /* [cgw]: 放弃模块使用权???? */

         module_put(owner);

         /* [cgw]: 获得kobj,退出 */

         if (kobj)

             return kobj;

         goto retry;

     }

     /* [cgw]: 退出临界区 */

     mutex_unlock(domain->lock);

     return NULL;

 }

 

 struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)

 {

     /* [cgw]: 分配一个struct kobj_map内存空间 */

     struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);

     /* [cgw]: 分配一个struct probe指针内存空间 */

     struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);

     int i;

 

     /* [cgw]: 分配失败 */

     if ((p == NULL) || (base == NULL)) {

         /* [cgw]: 释放内存空间 */

         kfree(p);

         kfree(base);

         return NULL;

     }

     /* [cgw]: 设置默认设备号为1,连续range个次设备,设置probe的实现

           * 函数(回调)

           */

     base->dev = ;

     base->range = ~;

     base->get = base_probe;

     /* [cgw]: 设置probes数组的初始值 */

     for (i = ; i < ; i++)

         p->probes[i] = base;

     p->lock = lock; 

219     return p;

220 }

上一篇:python学习(九)python中的变量、引用和对象的关系


下一篇:tree 查询出数据遍历tree