【翻译】device

原文:linux-2.6.34.1\Documentation\driver-model\device.txt

translated by:leonardo1019

2010年7月23日

基本的设备数据结构
~~~~~~~~~~~

struct device {
        struct list_head g_list;        /*全局设备链表中的节点*/
        struct list_head node;        /*父设备的子设备链表节点*/
        struct list_head bus_list;      /*总线的设备链表的节点*/
        struct list_head driver_list;      /*驱动程序的设备链表的节点*/
        struct list_head intf_list;      /*intf_data链表。对设备支持的每个接口都分配有一个结构体*/
        struct list_head children;      /*子设备链表*/
        struct device   * parent;      /**/

        char    name[DEVICE_NAME_SIZE];  /*ASCII设备描述。例如: " 3Com Corporation 3c905 100BaseTX [Boomerang]"*/
        char    bus_id[BUS_ID_SIZE];       /*ASCII,指示设备总线的位置。在所有该设备所在总线上的设备中,这个域应该是一个唯一的名字。

                       例如:PCI的bus_ids有如下形式:<bus number>:<slot number>.<function number> ,

                       这个名字是系统中所有PCI设备中唯一的*/

        spinlock_t      lock;              /*设备的自旋锁*/
        atomic_t        refcount;         /*设备的引用计数*/

        struct bus_type * bus;           /*指针。指向设备所属的struct bus_type*/
        struct driver_dir_entry dir;      /*设备的sysfs目录*/

    u32        class_num;                   /*设备的类枚举值*/

        struct device_driver *driver;    /*指针。指向控制该设备的驱动程序struct device_driver*/
        void            *driver_data;      /*驱动程序特定的数据*/
        void            *platform_data;  /*设备特定的platform数据。例如:对于特制板卡上的设备,比如嵌入式的或基于SOC的硬件,

                   Linux经常使用platform_data指针指向板卡特定的数据结构,该结构可以描述设备,描述设备的连线方式。

                   这就包括:哪个端口是可用的,芯片的变量,哪个GPIO引脚被用来做什么等等。

                   This shrinks the "Board Support Packages" (BSPs) and minimizes board-specific #ifdefs in drivers.*/

        u32             current_state;   /*当前的电源状态*/
        unsigned char *saved_state;      /**/

        void    (*release)(struct device * dev);  /*释放设备资源的回调函数。当该设备没被使用时调用。

                        它应该由分配设备资源的驱动程序设置(比如用于发现设备的总线驱动)*/
};

编程接口
~~~~~

发现设备的总线驱动程序使用编程接口向内核注册设备。

int device_register(struct device * dev);

总线驱动应该初始化以下四个域:

    - parent
    - name
    - bus_id
    - bus

当设备的引用计数将为0时,就被移出内核。引用计数可以用以下函数判断:

struct device * get_device(struct device * dev);
void put_device(struct device * dev);

如果引用计数不为0的话,get_device() 函数返回一个指针值,该指针指向传递给他的device结构体(如果它已经在被移除的进程中)

驱动程序可以用以下函数反问struct device中的lock:

void lock_device(struct device * dev);
void unlock_device(struct device * dev);

属性
~~~~

struct device_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct device *dev, struct device_attribute *attr,
            char *buf);
    ssize_t (*store)(struct device *dev, struct device_attribute *attr,
             const char *buf, size_t count);
};

设备属性可以由驱动程序导出,驱动程序仅简单的使用类似procfs的接口即可。

参考Documentation/filesystems/sysfs.txt查看关于sysfs的更多信息。

属性由DEVICE_ATTR宏声明:

#define DEVICE_ATTR(name,mode,show,store)

例:

DEVICE_ATTR(power,0644,show_power,store_power);

它声明了一个名叫'dev_attr_power'的struct device_attribute结构体。使用下面的函数来把它加入(移除)设备目录:

int device_create_file(struct device *device, struct device_attribute * entry);
void device_remove_file(struct device * dev, struct device_attribute * attr);

例:

device_create_file(dev,&dev_attr_power);
device_remove_file(dev,&dev_attr_power);

文件名是'power',访问权限是0644(-rw-r--r--)。

警告:虽然内核允许任何时候对某设备进行device_create_file()和
device_remove_file(),用户空间却对属性何时创建有严格的要求。当新设备注册到内核,内核会生成一个uevent通知用户空间(像udev)一个新设备准备好了。如果属性在设备注册之后加进去,用户空间则得不到通知也就不知道新属性的事情。

设备驱动在驱动探测时就发布附加的属性是非常重要的。如果设备驱动简单的在传递给它的device structure调用device_create_file()的话,用户空间则永远不会知晓新属性。取而代之的是,在modules_init函数中使用class_create()和class->dev_attrs去设置一个属性链表,然后在.probe(),然后使用device_create()去创建一个新设备作为探测到的设备的子设备。新的设备会生成新的uevent来向用户空间报告新属性。

例如:如果一个驱动程序想要添加如下属性:

struct device_attribute mydriver_attribs[] = {
    __ATTR(port_count, 0444, port_count_show),
    __ATTR(serial_number, 0444, serial_number_show),
    NULL
};

初始化函数应该是这样:

    mydriver_class = class_create(THIS_MODULE, "my_attrs");
    mydriver_class.dev_attr = mydriver_attribs;

假设struct device结构体'dev'是传递给探测函数的参数,驱动程序的探测函数要做如下事情:
create_device(&mydriver_class, dev, chrdev, &private_data, "my_name");

posted @ 2010-07-24 19:40  leonardo1019  阅读(636)  评论(0编辑  收藏  举报