Linux内核设备模型(3)

译者:郭少悲
2009/12/01

原文:linux-2.6/Documentation/driver-model/bus.txt

总线类型

定义
~~~~

struct bus_type {
    char            * name;

    struct subsystem    subsys;
    struct kset        drivers;
    struct kset        devices;

    struct bus_attribute    * bus_attrs;
    struct device_attribute    * dev_attrs;
    struct driver_attribute    * drv_attrs;

    int        (*match)(struct device * dev, struct device_driver * drv);
    int        (*hotplug) (struct device *dev, char **envp,
                    int num_envp, char *buffer, int buffer_size);
    int        (*suspend)(struct device * dev, pm_message_t state);
    int        (*resume)(struct device * dev);
};

int bus_register(struct bus_type * bus);


声明
~~~~

内核里的每一个总线类型(PCI,USB,等)应当声明一个静态的对象。它们必须初始
化name域,有时也初始化match()回调函数。

struct bus_type pci_bus_type = {
       .name    = "pci",
       .match    = pci_bus_match,
};

该数据结构应当被包含在一个头文件里,向相关的驱动导出:

extern struct bus_type pci_bus_type;


注册
~~~~~

总线驱动在初始化的时候,会调用bus_register()。它初始化总线对象的其余的域,
并将总线对象插入到总线类型的全局链表里。一旦总线对象被注册,
它的每个域对于总线驱动都是可用的。


回调函数
~~~~~~~~

match():关联驱动到设备
~~~~~~~~~~~~~~~~~~~~~~

设备的ID数据结构的格式和比较语法由其总线自己规定。驱动程序会在其对应的
总线驱动数据结构里定义一组它支持的设备ID集。

match()回调函数的目的是向总线提供机会, 通过将设备ID与驱动支持的ID集比较,
来判断是否指定的驱动支持指定的设备。这种方法不会牺牲总线的功能,或者牺牲总
线类型安全。

当驱动被注册到总线时,总线的设备链表会进行迭代,对那些还没有和驱动关联的设备
调用match()回调函数。


设备链表与驱动链表
~~~~~~~~~~~~~~~~~~

设备链表和驱动程序链表用来替代大多总线持有的本地链表。它们分别是struct device
和struct device_driver结构的链表。总线驱动可以自由的使用这些链表,但可能需要
转换为总线相关的数据类型。

Linux设备模型核心提供了迭代每个链表的帮助函数。

int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
             int (*fn)(struct device *, void *));

int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
             void * data, int (*fn)(struct device_driver *, void *));

这些帮助函数分别迭代每个链表,在链表里对每个设备或者驱动调用回调函数。
对链表的所有访问通过获取总线锁(读锁)而同步访问。在调用回调函数之前,链表里的每个
对象的引用计数增加,在访问下一个对象后减少。在调用回调函数时锁被释放。


sysfs
~~~~~~~~

在sysfs的顶层目录里,有个目录被命名为'bus'。

每个总线在bus目录里获得一个子目录,子目录里又包含两个默认目录:

    /sys/bus/pci/
    |-- devices
    `-- drivers

注册到总线上的驱动会在总线的驱动目录里获得一个子目录:

    /sys/bus/pci/
    |-- devices
    `-- drivers
        |-- Intel ICH
        |-- Intel ICH Joystick
        |-- agpgart
        `-- e100

挂载在某个总线上的设备被检测到后,会在总线的设备目录里获得一个符号链接,
该链接指向实际的设备目录层次。

    /sys/bus/pci/
    |-- devices
    |   |-- 00:00.0 -> ../../../root/pci0/00:00.0
    |   |-- 00:01.0 -> ../../../root/pci0/00:01.0
    |   `-- 00:02.0 -> ../../../root/pci0/00:02.0
    `-- drivers


导出属性
~~~~~~~~

struct bus_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct bus_type *, char * buf);
    ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};

总线驱动会通过BUS_ATTR宏导出属性,BUS_ATTR与DEVICE_ATTR类似。例如,如下定义:

static BUS_ATTR(debug,0644,show_debug,store_debug);

等价于声明:

static bus_attribute bus_attr_debug;

这可以用来对sysfs文件系统上的总线目录添加和删除属性,通过使用:

int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值