get_device_parent

struct kobject *virtual_device_parent(struct device *dev)
{
    static struct kobject *virtual_dir = NULL;

    if (!virtual_dir)
        virtual_dir = kobject_create_and_add("virtual", ///sys/devices/virtual
                             &devices_kset->kobj);

    return virtual_dir;
}

static struct kobject *
class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
{
    struct class_dir *dir;
    int retval;

    dir = kzalloc(sizeof(*dir), GFP_KERNEL);
    if (!dir)
        return ERR_PTR(-ENOMEM);

    dir->class = class;
    kobject_init(&dir->kobj, &class_dir_ktype);

    dir->kobj.kset = &class->p->glue_dirs;

    retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
    if (retval < 0) {
        kobject_put(&dir->kobj);
        return ERR_PTR(retval);
    }
    return &dir->kobj;
}

static struct kobject *get_device_parent(struct device *dev,
                     struct device *parent)
{
    if (dev->class) {
        struct kobject *kobj = NULL;
        struct kobject *parent_kobj;
        struct kobject *k;

#ifdef CONFIG_BLOCK
        /* block disks show up in /sys/block */
        if (sysfs_deprecated && dev->class == &block_class) {
            if (parent && parent->class == &block_class)
                return &parent->kobj;
            return &block_class.p->subsys.kobj;
        }
#endif

        /*
         * If we have no parent, we live in "virtual".
         * Class-devices with a non class-device as parent, live
         * in a "glue" directory to prevent namespace collisions.
         */
        if (parent == NULL)
            parent_kobj = virtual_device_parent(dev); //如果没有parent,暂时使用///sys/devices/virtual,后面进一步判断
        else if (parent->class && !dev->class->ns_type)
            return &parent->kobj; //找到了,直接返回
        else
            parent_kobj = &parent->kobj; //暂时使用parent的kobj,后面进一步判断

        mutex_lock(&gdp_mutex);

        /* find our class-directory at the parent and reference it */
        spin_lock(&dev->class->p->glue_dirs.list_lock);
        list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) //遍历class的glue_dirs(kset)中的kobj
            if (k->parent == parent_kobj) {  //如果glue_dirs中的kobj的parent是parent_kobj
                kobj = kobject_get(k);
                break;
            }
        spin_unlock(&dev->class->p->glue_dirs.list_lock);
        if (kobj) {
            mutex_unlock(&gdp_mutex);
            return kobj;
        }

  //如果如果glue_dirs中的kobj的parent没有合适的

        /* or create a new class-directory at the parent device */
        k = class_dir_create_and_add(dev->class, parent_kobj);
        /* do not emit an uevent for this simple "glue" directory */
        mutex_unlock(&gdp_mutex);
        return k;
    }

    /* subsystems can specify a default root directory for their devices */
    if (!parent && dev->bus && dev->bus->dev_root)
        return &dev->bus->dev_root->kobj;

    if (parent)
        return &parent->kobj;
    return NULL;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值