map.c 添加注释
来源:互联网 发布:mac安装ie浏览器 编辑:程序博客网 时间:2024/05/18 06:01
/* * linux/drivers/base/map.c * * (C) Copyright Al Viro 2002,2003 * Released under GPL v2. * * NOTE: data structure needs to be changed. It works, but for large dev_t * it will be too slow. It is isolated, though, so these changes will be * local to that file. */#include <linux/module.h>#include <linux/slab.h>#include <linux/mutex.h>#include <linux/kdev_t.h>#include <linux/kobject.h>#include <linux/kobj_map.h>struct kobj_map { struct probe { struct probe *next; dev_t dev; unsigned long range; struct module *owner; kobj_probe_t *get; int (*lock)(dev_t, void *); void *data; } *probes[255]; struct mutex *lock;};int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, struct module *module, kobj_probe_t *probe, int (*lock)(dev_t, void *), void *data){ /* [cgw]: 计算MAJOR(dev)到MAJOR(dev + range - 1)有几个 * 主设备,由于主设备号都一样,所以这里n = 1 */ unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; /* [cgw]: 以主设备号为索引 */ unsigned index = MAJOR(dev); unsigned i; struct probe *p; /* [cgw]: 主设备超出255个 */ if (n > 255) n = 255; /* [cgw]: 分配n个struct probe内存空间*/ p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL); /* [cgw]: 分配失败*/ if (p == NULL) return -ENOMEM; /* [cgw]: 填装n个struct probe,对应n个主设备号 * */ for (i = 0; i < n; i++, p++) { p->owner = module; p->get = probe; p->lock = lock; p->dev = dev; p->range = range; p->data = data; } /* [cgw]: 进入临界区*/ mutex_lock(domain->lock); /* [cgw]: 这里p -= n是因为,在以上for循环中,p++了n次 */ for (i = 0, p -= n; i < n; i++, p++, index++) { /* [cgw]: 根据当前索引,从probes[]中 * 取出一个probe */ struct probe **s = &domain->probes[index % 255]; /* [cgw]: probe是一个链表,每个新加入的节点, * 按照其range的大小,从小到大排列,即头结点的 * range是最小的 */ while (*s && (*s)->range < range) /* [cgw]: 继续查找下一个probe,直到其range大于 * 或等于新加入probe的range为止 */ s = &(*s)->next; /* [cgw]: 找到了一个probe,其range大于或等于新加入 * probe的range,把这个新加入的probe下一节点指向 * 这个probe节点 */ p->next = *s; /* [cgw]: 新加入的节点代替旧的位置 */ *s = p; } /* [cgw]: 退出临界区*/ mutex_unlock(domain->lock); return 0;}void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range){ /* [cgw]: 计算MAJOR(dev)到MAJOR(dev + range - 1)有几个 * 主设备,由于主设备号都一样,所以这里n = 1 */ unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; /* [cgw]: 以主设备号为索引 */ unsigned index = MAJOR(dev); unsigned i; struct probe *found = NULL; /* [cgw]: 主设备超出255个 */ if (n > 255) n = 255; /* [cgw]: 进入临界区*/ mutex_lock(domain->lock); for (i = 0; i < n; i++, index++) { struct probe **s; for (s = &domain->probes[index % 255]; *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) % 255]; 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 - 1 < dev) continue; /* [cgw]: 连续的次设备号个数超过最大范围,出错 */ if (p->range - 1 >= best) break; /* [cgw]: 模块引用失败???? */ if (!try_module_get(p->owner)) continue; /* [cgw]: 到此,找到了我们想要的那个probe,接着提取它的值 */ owner = p->owner; data = p->data; probe = p->get; best = p->range - 1; /* [cgw]: 计算这个要找的设备的次设备号,相对于找到的probe对应 * 设备号的次设备号的偏移,因为找到的probe对应设备号的次设备号 * 是这个设备的次设备号基址 */ *index = dev - p->dev; /* [cgw]: 未搞明白这个判断的意思 */ if (p->lock && p->lock(dev, data) < 0) { /* [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 = 1; base->range = ~0; base->get = base_probe; /* [cgw]: 设置probes数组的初始值 */ for (i = 0; i < 255; i++) p->probes[i] = base; p->lock = lock; return p; }
阅读全文
0 0
- map.c 添加注释
- C语言添加注释
- kobject.c 添加注释
- char_dev.c 添加中文注释
- class.c 添加中文注释(1)
- class.c 添加中文注释(2)
- class.c 添加中文注释(3)
- 添加注释
- 如何使用Doxygen为C添加标准化注释
- LinuxStudyNote(36)-Vim(2)-Vim使用技巧 :r、:map快捷键设置、:ab、添加注释快捷键、添加多行注释快捷键、邮箱添加快捷键
- C++STL:向map中添加元素的方法对比
- C 注释
- 添加用户信息注释
- 自动添加注释(转)
- 如何添加代码注释
- 如何添加代码注释
- XML 添加注释
- 添加表、字段注释
- Swift fatal error: unexpectedly found nil while unwrapping an Optional value?
- 正则表达式
- 关于Linux bash 中的变量
- linux平台编译java项目
- Android6.0中oat文件的加载过程
- map.c 添加注释
- HTML5 之图片上传预处理
- java 数组去掉重复数据和排序
- 数电第二章总结——逻辑代数基础
- java版的类似飞秋的局域网在线聊天项目
- mysql 小case
- opencv学习(十六)之颜色空间转换cvtColor()
- 从顺序表L中删除所有值为x的元素
- 变量的解构赋值