日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

学习《Linux设备模型浅析之设备篇》笔记(二)

發(fā)布時(shí)間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习《Linux设备模型浅析之设备篇》笔记(二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文件/drivers/base/platform.c

int __init platform_bus_init(void)

{
? ? ? ? int error;

? ? ? ?? early_platform_cleanup();

? ? ? ??error = device_register(&platform_bus);
? ? ? ??if (error)
? ? ? ??? ? ? ??return error;
? ? ? ??error = ? bus_register(&platform_bus_type);
? ? ? ??if (error)
? ? ? ??? ? ? ??device_unregister(&platform_bus);
? ? ? ??return error;

}


該源碼在《linux設(shè)備:初始化》中已經(jīng)粘貼過,是和devices_init()一起被driver_init(void)調(diào)用的,只不過當(dāng)時(shí)沒有深挖


文件/drivers/base/core.c

/**
?* device_add - 添加device到設(shè)備層
?* @dev: device.
?*
?* 這是device_register()的第二層, 不過如果device_initialize()已經(jīng)被
?* 調(diào)用過的話,它也可以被單獨(dú)調(diào)用。
?*
?* 這里通過kobject_add()添加@dev到 kobject 層, 添加它到全局和設(shè)備的
?* sibling(兄弟) lists,然后把它添加到驅(qū)動(dòng)module的其他相關(guān)子系統(tǒng)。
?*
?* 不要為任何device結(jié)構(gòu)調(diào)用該方法或device_register()超過一次。該
?* 模型核心不是為那些可以注銷掉之后再返回繼續(xù)使用的設(shè)備設(shè)計(jì)的。
?* (在其他部分,很難保證@dev的所有索引都已經(jīng)釋放了) 應(yīng)該要分配并
?* 注冊一個(gè)新的device結(jié)構(gòu)。
?*
?* NOTE: 在調(diào)用該方法之后絕對不要直接釋放 @dev,即使它返回一個(gè)
?* error! 應(yīng)該使用put_device()來釋放其索引。
?*/
int device_add(struct device *dev)
{
? ? ? ??struct device *parent = NULL;
? ? ? ??struct kobject *kobj;
? ? ? ??struct class_interface *class_intf;
? ? ? ??int error = -EINVAL;

? ? ? ??dev = get_device(dev);
? ? ? ??if (!dev)
? ? ? ??? ? ? ??goto done;

? ? ? ??if (!dev->p) {
? ? ? ??? ? ? ??error = device_private_init(dev);
? ? ? ??? ? ? ??if (error)
? ? ? ??? ? ? ??? ? ? ??goto done;
? ? ? ??}

? ? ? ??/*
? ? ? ??* for statically allocated devices, which should all be converted
? ? ? ??* some day, we need to initialize the name. We prevent reading back
? ? ? ??* the name, and force the use of dev_name()
? ? ? ??*/
? ? ? ??if (dev->init_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);
? ? ? ??kobj = get_device_parent(dev, parent);
? ? ? ??if (kobj)
? ? ? ??? ? ? ??dev->kobj.parent = kobj;

? ? ? ??/* use parent numa_node */
? ? ? ??if (parent)
? ? ? ??? ? ? ??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);
? ? ? ??if (error)
? ? ? ??? ? ? ??goto Error;

? ? ? ??/* notify platform of device entry */
? ? ? ??if (platform_notify)
? ? ? ??? ? ? ??platform_notify(dev);

? ? ? ??error = device_create_file(dev, &dev_attr_uevent);
? ? ? ??if (error)
? ? ? ??? ? ? ??goto attrError;

? ? ? ??if (MAJOR(dev->devt)) {
? ? ? ??? ? ? ??error = device_create_file(dev, &dev_attr_dev);
? ? ? ??? ? ? ??if (error)
? ? ? ??? ? ? ??? ? ? ??goto ueventattrError;

? ? ? ??? ? ? ??error = device_create_sys_dev_entry(dev);
? ? ? ??? ? ? ??if (error)
? ? ? ??? ? ? ??? ? ? ??goto devtattrError;

? ? ? ??? ? ? ??devtmpfs_create_node(dev);
? ? ? ??}

? ? ? ??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);

? ? ? ??/* Notify clients of device addition. ?該調(diào)用必須在dpm_sysfs_add()
? ? ? ??* 之后而在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);
? ? ? ??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);
? ? ? ??}
? ? ? ??done:
? ? ? ??put_device(dev);
? ? ? ??return error;
DPMError:
? ? ? ??bus_remove_device(dev);
?BusError:
? ? ? ??device_remove_attrs(dev);
?AttrsError:
? ? ? ??device_remove_class_symlinks(dev);
?SymlinkError:
? ? ? ??if (MAJOR(dev->devt))
? ? ? ??? ? ? ??devtmpfs_delete_node(dev);
? ? ? ??if (MAJOR(dev->devt))
? ? ? ??? ? ? ??device_remove_sys_dev_entry(dev);
devtattrError:
? ? ? ??if (MAJOR(dev->devt))
? ? ? ??? ? ? ??device_remove_file(dev, &dev_attr_dev);
ueventattrError:
? ? ? ??device_remove_file(dev, &dev_attr_uevent);
?attrError:
? ? ? ??kobject_uevent(&dev->kobj, KOBJ_REMOVE);
? ? ? ??kobject_del(&dev->kobj);
?Error:
? ? ? ??cleanup_device_parent(dev);
? ? ? ??if (parent)
? ? ? ??? ? ? ??put_device(parent);
name_error:
? ? ? ??kfree(dev->p);
? ? ? ??dev->p = NULL;
? ? ? ??goto done;
}

總結(jié)

以上是生活随笔為你收集整理的学习《Linux设备模型浅析之设备篇》笔记(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。