zoukankan      html  css  js  c++  java
  • 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[255];
     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 - 1) - MAJOR(dev) + 1;
     40     /* [cgw]: 以主设备号为索引 */
     41     unsigned index = MAJOR(dev);
     42     unsigned i;
     43     struct probe *p;
     44 
     45     /* [cgw]: 主设备超出255个 */
     46     if (n > 255)
     47         n = 255;
     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 = 0; 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 = 0, p -= n; i < n; i++, p++, index++) {
     68         /* [cgw]: 根据当前索引,从probes[]中
     69               * 取出一个probe
     70               */
     71         struct probe **s = &domain->probes[index % 255];
     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 0;
     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 - 1) - MAJOR(dev) + 1;
    100     /* [cgw]: 以主设备号为索引 */
    101     unsigned index = MAJOR(dev);
    102     unsigned i;
    103     struct probe *found = NULL;
    104     /* [cgw]: 主设备超出255个 */
    105     if (n > 255)
    106         n = 255;
    107     /* [cgw]: 进入临界区*/
    108     mutex_lock(domain->lock);
    109     
    110     for (i = 0; i < n; i++, index++) {
    111         struct probe **s;
    112         for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
    113             struct probe *p = *s;
    114             /* [cgw]: 找到这个设备,并且其对应的次设备号个数也匹配 */
    115             if (p->dev == dev && p->range == range) {
    116                 /* [cgw]: 这个设备对应的节点,被下一节点取代,即移除
    117                       * 这个节点
    118                       */
    119                 *s = p->next;
    120                 /* [cgw]: 记录这个节点 */
    121                 if (!found)
    122                     found = p;
    123                 break;
    124             }
    125         }
    126     }
    127     /* [cgw]: 退出临界区*/
    128     mutex_unlock(domain->lock);
    129     /* [cgw]: 释放这个节点对应的内存空间 */
    130     kfree(found);
    131 }
    132 
    133 struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
    134 {
    135     struct kobject *kobj;
    136     struct probe *p;
    137     unsigned long best = ~0UL;
    138 
    139 retry:  /* [cgw]: 重试 */
    140     /* [cgw]: 进入临界区 */
    141     mutex_lock(domain->lock);
    142     /* [cgw]: 以主设备号为索引,从probes数组取出一个probe */
    143     for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
    144         struct kobject *(*probe)(dev_t, int *, void *);
    145         struct module *owner;
    146         void *data;
    147 
    148         /* [cgw]: 取出的这个probe对应的设备号大于要查找的设备号
    149                   * 或 这个probe对应的设备号的最大次设备号小于要查找的设备号
    150                   * 即不在查找范围内,那么返回,继续取出下一个probe
    151                   */
    152         if (p->dev > dev || p->dev + p->range - 1 < dev)
    153             continue;
    154         /* [cgw]: 连续的次设备号个数超过最大范围,出错
    155           */
    156         if (p->range - 1 >= best)
    157             break;
    158         /* [cgw]: 模块引用失败???? */
    159         if (!try_module_get(p->owner))
    160             continue;
    161         /* [cgw]: 到此,找到了我们想要的那个probe,接着提取它的值 */
    162         owner = p->owner;
    163         data = p->data;
    164         probe = p->get;
    165         best = p->range - 1;
    166         /* [cgw]: 计算这个要找的设备的次设备号,相对于找到的probe对应
    167           * 设备号的次设备号的偏移,因为找到的probe对应设备号的次设备号
    168           * 是这个设备的次设备号基址
    169           */
    170         *index = dev - p->dev;
    171         /* [cgw]: 未搞明白这个判断的意思 */
    172         if (p->lock && p->lock(dev, data) < 0) {
    173             /* [cgw]: 放弃模块使用权???? */
    174             module_put(owner);
    175             continue;
    176         }
    177         /* [cgw]: 退出临界区 */
    178         mutex_unlock(domain->lock);
    179         /* [cgw]: 调用probe的实现函数,并返回对应的kobj */
    180         kobj = probe(dev, index, data);
    181         /* Currently ->owner protects _only_ ->probe() itself. */
    182         /* [cgw]: 放弃模块使用权???? */
    183         module_put(owner);
    184         /* [cgw]: 获得kobj,退出 */
    185         if (kobj)
    186             return kobj;
    187         goto retry;
    188     }
    189     /* [cgw]: 退出临界区 */
    190     mutex_unlock(domain->lock);
    191     return NULL;
    192 }
    193 
    194 struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)
    195 {
    196     /* [cgw]: 分配一个struct kobj_map内存空间 */
    197     struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
    198     /* [cgw]: 分配一个struct probe指针内存空间 */
    199     struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
    200     int i;
    201 
    202     /* [cgw]: 分配失败 */
    203     if ((p == NULL) || (base == NULL)) {
    204         /* [cgw]: 释放内存空间 */
    205         kfree(p);
    206         kfree(base);
    207         return NULL;
    208     }
    209     /* [cgw]: 设置默认设备号为1,连续range个次设备,设置probe的实现
    210           * 函数(回调)
    211           */
    212     base->dev = 1;
    213     base->range = ~0;
    214     base->get = base_probe;
    215     /* [cgw]: 设置probes数组的初始值 */
    216     for (i = 0; i < 255; i++)
    217         p->probes[i] = base;
    218     p->lock = lock; 

    219     return p;

    220 }

  • 相关阅读:
    进制
    流程控制
    运算符
    格式化输出
    数据结构-树的遍历
    A1004 Counting Leaves (30分)
    A1106 Lowest Price in Supply Chain (25分)
    A1094 The Largest Generation (25分)
    A1090 Highest Price in Supply Chain (25分)
    A1079 Total Sales of Supply Chain (25分)
  • 原文地址:https://www.cnblogs.com/hackfun/p/5696289.html
Copyright © 2011-2022 走看看