class_create
来源:互联网 发布:在线监测数据造假 编辑:程序博客网 时间:2024/05/20 15:42
class_create函数跟踪:
/* This is a #define to keep the compiler from merging different
* instances of the __key variable */
#define class_create(owner, name) \
({ \
static struct lock_class_key __key;\
__class_create(owner, name, &__key);\
})
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
* @name: pointer to a string for the name of this class.
* @key: the lock_class_key for this class; used by mutex lock debugging
*
* This is used to create a struct class pointer that can then be used
* in calls to device_create().
*
* Returns &struct class pointer on success, or ERR_PTR() on error.
*
* Note, the pointer created here is to be destroyed when finished by
* making a call to class_destroy().
*/
struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
{
struct class *cls;
int retval;
cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
retval = -ENOMEM;
goto error;
}
cls->name = name;
cls->owner = owner;
cls->class_release = class_create_release;
retval = __class_register(cls, key);
if (retval)
goto error;
return cls;
error:
kfree(cls);
return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(__class_create);
static void class_create_release(struct class *cls)
{
pr_debug("%s called for %s\n", __func__, cls->name);
kfree(cls);
}
int __class_register(struct class *cls, struct lock_class_key *key)
{
struct subsys_private *cp;
int error;
pr_debug("device class '%s': registering\n", cls->name);
cp = kzalloc(sizeof(*cp), GFP_KERNEL);
if (!cp)
return -ENOMEM;
klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
INIT_LIST_HEAD(&cp->interfaces);
kset_init(&cp->glue_dirs);
__mutex_init(&cp->mutex, "subsys mutex", key);
error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
if (error) {
kfree(cp);
return error;
}
/* set the default /sys/dev directory for devices of this class */
if (!cls->dev_kobj)
cls->dev_kobj = sysfs_dev_char_kobj;
#if defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */
if (!sysfs_deprecated || cls != &block_class)
cp->subsys.kobj.kset = class_kset;
#else
cp->subsys.kobj.kset = class_kset;
#endif
cp->subsys.kobj.ktype = &class_ktype;
cp->class = cls;
cls->p = cp;
error = kset_register(&cp->subsys);
if (error) {
kfree(cp);
return error;
}
error = add_class_attrs(class_get(cls));
class_put(cls);
return error;
}
EXPORT_SYMBOL_GPL(__class_register);
先跟踪3层,不能再多了。
- class_create()
- class_create()
- class_create()
- class_create()
- class_create()
- class_create
- class_create()
- class_create
- class_create()
- class_create()
- class_create
- class_create
- class_create() class_device_create
- register_chrdev,class_create()
- class_create() 2
- class_create() device_create()
- class_create() 详解
- register_chrdev,class_create()
- Android 格子菜单 Xamarin
- 三角形
- HttpClient 4.3详细教程之HTTP认证
- 如何阅读书籍
- 用户名+is not in the sudoers file. This incident will be reported.
- class_create
- VS调试-附加到进程
- Codeforces327C Magic Five[组合数学]
- 自己动手实现集合框架类(四)之LinkedHashMap
- python selenium 获取动态网页数据
- shell进度条
- 小仙女-Jquery基础
- C++开源代码项目汇总 (转)
- 【Oracle学习笔记】单行函数