九、get_device_parent 的作用

在dev->class 成立的情况下,

(1)对于没有指定dev->parent的dev都将被添加到/sys/devices/virtual/tty/ 目录下

(2)如果指定了dev ->parent , 那么同时该dev ->class存在 , 同时parent -> class存在 ,
那么该dev ->name目录将被添加到parent->class所在目录下 [ luther . gliethttp ]

luther@gliethttp : ~ $  ll  / sys / class / tty / console
lrwxrwxrwx 1 root root 0 2009 - 06 - 30 09 : 40  / sys / class / tty / console  - >   . . / . . / devices / virtual / tty / console
luther@gliethttp : ~ $  ll  / sys / devices / virtual / tty / console /
total 0
- rw - r - - r - -  1 root root 4 . 0K 2009 - 06 - 30 10 : 51 uevent
drwxr - xr - x 2 root root 0 2009 - 06 - 30 10 : 51 power
lrwxrwxrwx 1 root root 0 2009 - 06 - 30 10 : 57 subsystem  - >   . . / . . / . . / . . / class / tty
- r - - r - - r - -  1 root root 4 . 0K 2009 - 06 - 30 10 : 57 dev

来看看linux2 . 6 . 25内核源码 , 是怎么做得 .

device_create ( tty_class ,   NULL ,  MKDEV ( TTYAUX_MAJOR ,  1 ) ,   "console" ) ;
= = > device_register
= = > device_add
= = > setup_parent
= = > get_device_parent
= = > dev - > kobj . parent  =  kobj ( "/sys/devices/virtual/tty" ) ; //所以所有的文件添加都将指向该目录[luther.gliethttp]

# ifdef  CONFIG_SYSFS_DEPRECATED
static   struct  kobject  * get_device_parent ( struct  device  * dev ,
                      struct  device  * parent )
{
     /* class devices without a parent live in /sys/class// */
     if   ( dev - > class   & &   ( ! parent  | |  parent - > class   ! =  dev - > class ) )
         return   & dev - > class - > subsys . kobj ;
     /* all other devices keep their parent */
     else   if   ( parent )
         return   & parent - > kobj ;

     return   NULL ;
}
# else
// 在我的ubnutu 8.10中使用的如下函数

static   struct  kobject  * get_device_parent ( struct  device  * dev ,
                      struct  device  * parent )
{
     int  retval ;

     if   ( dev - > class )   {
         struct  kobject  * kobj  =   NULL ;
         struct  kobject  * parent_kobj ;
         struct  kobject  * k ;

         /*
         * 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 ) ;   // 获取/sys/devices/virtual目录对应的kobj

         else   if   ( parent - > class )
             return   & parent - > kobj ;
         else
            parent_kobj  =   & parent - > kobj ;

         /* find our class-directory at the parent and reference it */
        spin_lock ( & dev - > class - > class_dirs . list_lock ) ;
         // class->class_dirs本身就是一个kset

         // 如果该kset的list链表上没有挂接到/sys/devices/virtual目录上的son,那么说明该class_dirs还没有在

         // /sys/devices/virtual目录下创建,所以就需要创建该class名对应的目录[luther.gliethttp]

        list_for_each_entry ( k ,   & dev - > class - > class_dirs . list ,  entry )
             if   ( k - > parent  = =  parent_kobj )   {
                kobj  =  kobject_get ( k ) ;
                 break ;
             }
        spin_unlock ( & dev - > class - > class_dirs . list_lock ) ;
         if   ( kobj )
             return  kobj ;
         // 创建/sys/devices/virtual/tty这个tty_class对应的目录

         /* or create a new class-directory at the parent device */
        k  =  kobject_create ( ) ;
         if   ( ! k )
             return   NULL ;
        k - > kset  =   & dev - > class - > class_dirs ;   // 名在/sys/devices/virtual/目录下创建以tty_class的name为目录名的目录[luther.gliethttp]

        retval  =  kobject_add ( k ,  parent_kobj ,   "%s" ,  dev - > class - > name ) ;   // 将kobj添加到parent_kobj对应目录下[luther.gliethttp]

         if   ( retval  <  0 )   {
            kobject_put ( k ) ;
             return   NULL ;
         }
         /* do not emit an uevent for this simple "glue" directory */
         return  k ;
     }

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

#endif


static struct kobject *get_device_parent(struct device *dev,
struct device *parent)
{
if (dev->class) { //设备的类 存在,sys/class/目录下的的那一个类,例如video4linux 等
static DEFINE_MUTEX(gdp_mutex);
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); //虚拟设备父设备,对象为:sys/devices/virtual

接下来后面创建类目录
else if (parent->class && !dev->class->ns_type)  //父设备类存在且设备类命名空间类型不存在
return &parent->kobj;   返回父设备的对象,退出此函数
else //父设备parent存在,parent->class不存在,dev->class->nstype存在
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)
if (k->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;
}


/* 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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值