struct device结构体(2.6.23)

一、定义:
linux/include/linux/device.h

 407struct 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中,原型是:
  21struct 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,原型是:
  32struct 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中,原型是:
 337struct 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中被实现:
 898int 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
1044void 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对象的引用计数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值