linux 看设备对应的驱动,面试如果被问到Linux设备驱动模型怎么答?看完这篇就能给出满意答案了...

int device_add(struct device *dev)

{

struct device *parent = NULL;

struct kobject *kobj;

struct class_interface *class_intf;

int error = -EINVAL;

struct kobject *glue_dir = NULL;

dev = get_device(dev);//增加设备的kobject的引用计数

if (!dev)

goto done;

if (!dev->p) {

error = device_private_init(dev);//初始化dev的私有成员,及其链表操作函数

if (error)

goto done;

}

if (dev->init_name) {//保存设备名,以后需要获取时使用dev_name函数获取

dev_set_name(dev, '%s', dev->init_name);

dev->init_name = NULL;

}

/* subsystems can specify simple device enumeration */

if (!dev_name(dev) && dev->bus && dev->bus->dev_name)

dev_set_name(dev, '%s%u', dev->bus->dev_name, dev->id);

if (!dev_name(dev)) {

error = -EINVAL;

goto name_error;

}

pr_debug('device: '%s': %s\n', dev_name(dev), __func__);

parent = get_device(dev->parent);//返回父节点,增加父节点引用计数,如果没有返回NULL

kobj = get_device_parent(dev, parent);//以上层devices为准重设dev->kobj.parent

if (kobj)

dev->kobj.parent = kobj;

/* use parent numa_node */

if (parent && (dev_to_node(dev) == NUMA_NO_NODE))

set_dev_node(dev, dev_to_node(parent));

/* first, register with generic layer. */

/* we require the name to be set before, and pass NULL */

error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);//设置dev->kobj的名字和父对象,并建立相应目录

if (error) {

glue_dir = get_glue_dir(dev);

goto Error;

}

/* notify platform of device entry */

if (platform_notify)

platform_notify(dev);

error = device_create_file(dev, &dev_attr_uevent);//建立uevent属性文件

if (error)

goto attrError;

error = device_add_class_symlinks(dev);

if (error)

goto SymlinkError;

error = device_add_attrs(dev);

if (error)

goto AttrsError;

error = bus_add_device(dev);

if (error)

goto BusError;

error = dpm_sysfs_add(dev);

if (error)

goto DPMError;

device_pm_add(dev);

if (MAJOR(dev->devt)) {

error = device_create_file(dev, &dev_attr_dev);//在sys下产生dev属性文件

if (error)

goto DevAttrError;

error = device_create_sys_dev_entry(dev);//在/sys/dev目录建立对设备的软链接

if (error)

goto SysEntryError;

devtmpfs_create_node(dev);

}

/* Notify clients of device addition.  This call must come

* after dpm_sysfs_add() and before kobject_uevent().

*/

if (dev->bus)

blocking_notifier_call_chain(&dev->bus->p->bus_notifier,

BUS_NOTIFY_ADD_DEVICE, dev);

kobject_uevent(&dev->kobj, KOBJ_ADD);//向用户空间发出KOBJ_ADD 事件

bus_probe_device(dev);//检测驱动中有无适合的设备进行匹配,现在只添加了设备,还没有加载驱动,所以不会进行匹配

if (parent)

klist_add_tail(&dev->p->knode_parent,

&parent->p->klist_children);//把该设备的节点挂到其父节点的链表

if (dev->class) {

mutex_lock(&dev->class->p->mutex);

/* tie the class to the device */

klist_add_tail(&dev->knode_class,

&dev->class->p->klist_devices);

/* notify any interfaces that the device is here */

list_for_each_entry(class_intf,

&dev->class->p->interfaces, node)

if (class_intf->add_dev)

class_intf->add_dev(dev, class_intf);

mutex_unlock(&dev->class->p->mutex);

}

/*省略部分error内容*/

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值