·ChinaUnix首页 ·论坛 ·博客 
Linux首页 | Linux新闻 | Linux文档 | Linux论坛 | Linux下载 | Linux博客 | Linux搜索
新手入门 | 安装启动 | 管理员指南 | 开发手册 | 桌面应用 | 程序开发 | 数据库 | 网络技术| CentOS | Fedora | MySQL | Apache | Ubuntu | Gentoo| OSCON08
  Linux时代 >> 技术文档 >> 程序开发
 
struct device结构体(2.6.23)
来源: ChinaUnix博客  日期: 2008.07.23 22:19 (共有条评论) 我要评论
 

                                                                                                                                                一、定义:
linux/include/linux/device.h
407
struct
device
{
408
        struct
klist
            
klist_children
;
409
        struct
klist_node
      
knode_parent
;           /* node in sibling list */
410
        struct
klist_node
      
knode_driver
;
411
        struct
klist_node
      
knode_bus
;
412
        struct
device
           *
parent
;
413
414
        struct
kobject

kobj
;
415
        char   
bus_id
[
BUS_ID_SIZE
];    /* position on parent bus */
416
        struct
device_type
      *
type
;
417
        unsigned               
is_registered
:1;
418
        unsigned               
uevent_suppress
:1;
419
420
        struct
semaphore
        
sem
;    /* semaphore to synchronize calls to
421
                                         * its driver.
422
                                         */
423
424
        struct
bus_type
*
bus
;          /* type of bus device is on */
425
        struct
device_driver
*
driver
;   /* which driver has allocated this
426
                                           device */
427
        void            *
driver_data
;   /* data private to the driver */
428
        void            *
platform_data
; /* Platform specific data, device
429
                                           core doesn't touch it */
430
        struct
dev_pm_info
      
power
;
431
432
#ifdef
CONFIG_NUMA
433
        int            
numa_node
;      /* NUMA node this device is close to */
434
#endif
435
        
u64
             *
dma_mask
;      /* dma mask (if dma'able device) */
436
        
u64
            
coherent_dma_mask
;/* Like dma_mask, but for
437
                                             alloc_coherent mappings as
438
                                             not all hardware supports
439
                                             64 bit addresses for consistent
440
                                             allocations such descriptors. */
441
442
        struct
list_head
        
dma_pools
;      /* dma pools (if dma'ble) */
443
444
        struct
dma_coherent_mem
*
dma_mem
; /* internal for coherent mem
445
                                             override */
446
        /* arch specific additions */
447
        struct
dev_archdata
     
archdata
;
448
449
        
spinlock_t
              
devres_lock
;
450
        struct
list_head
        
devres_head
;
451
452
        /* class_device migration path */
453
        struct
list_head
        
node
;
454
        struct
class
            *
class
;
455
        
dev_t
                  
devt
;           /* dev_t, creates the sysfs "dev" */
456
        struct
attribute_group
  **
groups
;       /* optional groups */
457
458
        void    (*
release
)(struct
device
*
dev
);
459
};
二、作用:
用于描述设备相关的信息设备之间的层次关系,以及设备与总线、驱动的关系。
三、详解:
1、struct klist            klist_children;
struct klist被定义在linux/include/linux/klist.h中,原型是:
  21
struct
klist
{
  22
        
spinlock_t
              
k_lock
;
  23
        struct
list_head
        
k_list
;
  24
        void                    (*
get
)(struct
klist_node
*);
  25
        void                    (*
put
)(struct
klist_node
*);
  26
};
可见它是对struct list_head的扩展,在此它的作用是连接设备列表中的孩子列表。
2、struct klist_node       knode_parent; /* node in sibling list */
struct klist_node被定义在linux/include/linux/klist.h,原型是:
  32
struct
klist_node
{
  33
        struct
klist
            *
n_klist
;
  34
        struct
list_head
        
n_node
;
  35
        struct
kref
            
n_ref
;
  36
        struct
completion
      
n_removed
;
  37
};
在此它的作用是表示它的兄弟节点。
3、struct klist_node       knode_driver;
表示它的驱动节点。
4、struct klist_node       knode_bus;
表示总线节点。
5、struct device           *parent;
指向其父设备。
6、struct kobject kobj;
这里
http://blog.chinaunix.net/u1/55599/showart.php?id=1086478
有对kobject的解释,此处它是内嵌的一个kobject对象。
7、char    bus_id[BUS_ID_SIZE];  
bus_id表示其在父总线上的位置。BUS_ID_SIZE被定义为:
#define KOBJ_NAME_LEN 20 /*linux/include/linux/kobject.h*/
#define BUS_ID_SIZE KOBJ_NAME_LEN  /*linux/include/linux/device.h*/
所以表示位置的字符串长度不能超过20。
8、struct device_type      *type;
被定义在/linux/include/linux/device.h中,原型是:
337
struct
device_type
{
338
        const char *
name
;
339
        struct
attribute_group
**
groups
;
340
        int (*
uevent
)(struct
device
*
dev
, char **
envp
, int
num_envp
,
341
                      char *
buffer
, int
buffer_size
);
342
        void (*
release
)(struct
device
*
dev
);
343
        int (*
suspend
)(struct
device
*
dev
,
pm_message_t

state
);
344
        int (*
resume
)(struct
device
*
dev
);
345
};
device_type结构表示设备的类型。一个设备类或者总线可以包含不同类型的设备,例如“分区”和“磁盘” , “鼠标”和“事件” 。device_type就可以标识某个设备类型和该设备的特有信息,它就等同于kobject结构中的kobj_type一样。如果name数据成员被指定,那么uevent成员函数就会把它包含在DEVTYPE变量中。
9、unsigned is_registered:1;
标识该设备是否已经被注册过。is_registered:1这样的形式表示is_registered这个变量只有一位。在32位linux系统下,unsigned是4字节32位,而经过is_registered:1这样的限制后,变量is_registered只有一位,其取值只能是1或者0,相当于声明了一个boolean类型的变量。在此种用法中,后面指定数据宽度的值只能大于0且小于本身的数据宽度。
10、struct bus_type * bus;
指向所连接总线的指针。
11、struct device_driver *driver;
指向被分配到该设备的设备驱动。
12、u64 *dma_mask;    /*指向设备DMA屏蔽字。*/
u64 coherent_dma_mask;/*设备一致性DMA的屏蔽字。*/
struct list_head dma_pools;  /*聚集的DMA缓冲池。*/
struct dma_coherent_mem *dma_mem; /*指向设备所使用的一致性DMA存储器描述符的指针*/
13、spinlock_t devres_lock;
定义一个设备自旋锁,用于互斥访问设备。关于自旋锁的详细讲解参考:
http://www.deansys.com/doc/ldd3/ch05s05.html
14、void    (*release)(struct device * dev);
释放设备描述符的回调函数。
四、操作:
linux内核系统了一系列完整的对device操作的函数。
1、其中device_register()函数用来将一个新的device对象插入设备模型。它在linux/drivers/base/core.c中被实现:
898
int
device_register
(struct
device
*
dev
)
899
{
900
        
device_initialize
(
dev
);
901
        return
device_add
(
dev
);
902
}
该函数首先是调用device_initialize()初始化device结构,具体是初始化嵌入的kobject结构dev->kobj,初始化列表中的孩子列表kobj->klist_children,初始化DMA缓冲池dev->dma_pools,初始化自旋锁dev->devres_lock等。接下来device_add()函数才真正将该device对象dev插入设备模型中。device_add()函数首先是通过kboject_add()函数将它添加到kobject层次,再把它添加都全局和兄弟链表中,最后添加到其他相关的子系统的驱动程序模型,完成device对象的注册。
2、device_unregister()完成相反的过程:/linux/drivers/base/core.c
1044
void
device_unregister
(struct
device
*
dev
)
1045
{
1046
        
pr_debug
("DEV: Unregistering device. ID = '%s'\n",
dev
->
bus_id
);
1047
        
device_del
(
dev
);
1048
        
put_device
(
dev
);
1049
}
它会先以KERN_DEBUG级别打印注销设备的信息,然后才真正删除设备,减少设备对象的引用计数。
3、get_device()和put_device()分别是增加和减少设备对象的引用计数。这两个函数都定义在:/linux/drivers/base/core.c中。具体是应用在注册device对象时,device_add()函数会调用get_device()增加对该device对象的引用计数。在注销设备对象时,device_unregister()函数直接调用put_device()函数减少对该device对象的引用计数。


               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73528/showart_1090200.html
  发表评论 查看评论(共有条评论)
 
 


最新资讯更多>> 
· OpenMoko面临MP3专利困局
· Windows 7生不逢时 Linux能否成..
· Mozilla主席贝克专访:不惧Chr..
· Sun麦克尼利暗讽IBM微软 倡导I..
· 微软牵手Novell两周年:争议和抵..
· 微软、Novell合作两周年庆 再推..
· 红帽虚拟化全面中标新联通IDC建..
· 袁萌:开源软件需告别误区
· 综述:Solaris能否成为Sun的救星
· Linux平台刻录工具NeroLINUX 3..
论坛热点更多>> 
· 为什么业界对firefox一片叫好?
· 各地车展 合集
· 蚊子MM生活照-真实
· 大连车展
· 各式各样的清纯
· 精选车模
· 各地车展 合集二
· 你是否已经审美疲劳了?(网..
· 您最希望沙龙活动的所在地:..
· 自己修改的ADC0809驱动,God..
文档更新更多>> 
· 提供SPI/SDIO接口的小尺寸wi-fi模..
· ubuntu pdf乱码、方块字
· 解析linux根文件系统的挂载过程
· linux开机启动脚本的顺序
· phpMyAdmin 3.1.0 Beta 1 - MySQ..
· Linux 内核的WorkQueues API做了..
· 纠正了aMule中的文件名乱码
· rhel5系统的安装
· 算法合集一、数论算法 1.求两数..
· 【转自外文】用SD卡模拟CDROM光盘..
 
关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 友情链接 | 免费注册

Copyright © 2001-2008 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们

京ICP证041476号