您的位置:首页 > 运维架构 > Linux

linux 驱动中几个驱动注册的实体函数

2017-08-15 10:47 603 查看
misc_register() 调用device_create_with_groups()(新内核, 旧的为device_create()) 函数进行注册,

int misc_register(struct miscdevice * misc)
{
dev_t dev;
int err = 0;
bool is_dynamic = (misc->minor == MISC_DYNAMIC_MINOR);

INIT_LIST_HEAD(&misc->list);

mutex_lock(&misc_mtx);

if (is_dynamic) {
int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
if (i >= DYNAMIC_MINORS) {
err = -EBUSY;
goto out;
}
misc->minor = DYNAMIC_MINORS - i - 1;
set_bit(i, misc_minors);
} else {
struct miscdevice *c;

list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
err = -EBUSY;
goto out;
}
}
}

dev = MKDEV(MISC_MAJOR, misc->minor);

misc->this_device =
device_create_with_groups(misc_class, misc->parent, dev,
misc, misc->groups, "%s", misc->name);
if (IS_ERR(misc->this_device)) {
if (is_dynamic) {
int i = DYNAMIC_MINORS - misc->minor - 1;

if (i < DYNAMIC_MINORS && i >= 0)
clear_bit(i, misc_minors);
misc->minor = MISC_DYNAMIC_MINOR;
}
err = PTR_ERR(misc->this_device);
goto out;
}

/*
* Add it to the front, so that later devices can "override"
* earlier defaults
*/
list_add(&misc->list, &misc_list);
out:
mutex_unlock(&misc_mtx);
return err;
}


misc_deregister() 代码为

void misc_deregister(struct miscdevice *misc)
{
int i = DYNAMIC_MINORS - misc->minor - 1;

if (WARN_ON(list_empty(&misc->list)))
return;

mutex_lock(&misc_mtx);
list_del(&misc->list);
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i >= 0)
clear_bit(i, misc_minors);
mutex_unlock(&misc_mtx);
}


device_create_with_groups() 及 device_create() 是两个常用的创建及注册设备, 同时创建/sys/文件系统的的函数, 如/sys/class/gpio/* 中的文件,通过读写文件可以控制相关驱动及设备

device_create_with_groups() 及 device_create() 最终调用 device_create_groups_vargs()函数;

static struct device *
device_create_groups_vargs(struct class *class, struct device *parent,
dev_t devt, void *drvdata,
const struct attribute_group **groups,
const char *fmt, va_list args)
{
struct device *dev = NULL;
int retval = -ENODEV;

if (class == NULL || IS_ERR(class))
goto error;

dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
retval = -ENOMEM;
goto error;
}

device_initialize(dev);
dev->devt = devt;
dev->class = class;
dev->parent = parent;
dev->groups = groups;
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);

retval = kobject_set_name_vargs(&dev->kobj, fmt, args); //创建文件系统
if (retval)
goto error;

retval = device_add(dev); //注册设备
if (retval)
goto error;

return dev;

error:
put_device(dev);
return ERR_PTR(retval);
}


cdev_add() 增加一个字符型设备, 通用方法

int err, devno = MKDEV(globalmem_major, index);

cdev_init(&dev->cdev, &globalmem_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux-驱动