Documentation_driver-model_driver.txt

Chinese translated version of Documentation/driver-model/driver.txt

If you have any comment or update to the content, please contact the
original document maintainer directly.  However, if you have a problem
communicating in English you can also ask the Chinese maintainer for
help.  Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation.


Chinese maintainer: 马煜晨 380319072@qq.com
---------------------------------------------------------------------

Documentation/driver-model/driver.txt的中文翻译


如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
译存在问题,请联系中文版维护者。


中文版维护者: 马煜晨  <380319072@qq.com>
中文版翻译者: 马煜晨  <380319072@qq.com>
中文版校译者: 马煜晨  <380319072@qq.com>

以下为正文
---------------------------------------------------------------------

 

 


Device Drivers

See the kerneldoc for the struct device_driver.

设备驱动程序

下面介绍device_driver结构的kerneldoc

Allocation
~~~~~~~~~~

Device drivers are statically allocated structures. Though there may
be multiple devices in a system that a driver supports, struct
device_driver represents the driver as a whole (not a particular
device instance).

分配
~~~~~~~~~~

设备驱动程序是静态分配的结构。虽然可能在一个由一个驱动程序支持的多个设
备的系统中,结构device_driver作为一个整体的驱动程序(而不是一个特定的设
备实例)

Initialization
~~~~~~~~~~~~~~

The driver must initialize at least the name and bus fields. It should
also initialize the devclass field (when it arrives), so it may obtain
the proper linkage internally. It should also initialize as many of
the callbacks as possible, though each is optional.

初始化
~~~~~~~~~~~~~~

这个驱动程序必须初始化名字和总线字段。它也应该初始化devclass的字段(当
它到达),所以它可能获得适当的内部联动。它还应该尽可能地初始化更多的回
调函数,尽管每个都是可选择的。

Declaration
~~~~~~~~~~~

As stated above, struct device_driver objects are statically
allocated. Below is an example declaration of the eepro100
driver. This declaration is hypothetical only; it relies on the driver
being converted completely to the new model.

声明
~~~~~~~~~~~
如上所诉,结构device_driver的对象是静态分配。下面是一个eepro100驱动程序
的声明例子。该声明仅仅是一个假设,它依赖于驱动程序完全转换成新的模式。

static struct device_driver eepro100_driver = {
       .name  = "eepro100",
       .bus  = &pci_bus_type,
      
       .probe  = eepro100_probe,
       .remove  = eepro100_remove,
       .suspend  = eepro100_suspend,
       .resume  = eepro100_resume,
};

Most drivers will not be able to be converted completely to the new
model because the bus they belong to has a bus-specific structure with
bus-specific fields that cannot be generalized.

大多数驱动程序将不能完全被转换到新的模式,因为它们归属的总线具有特定于总
线的结构与总线特定的领域,不能一概而论。

The most common example of this are device ID structures. A driver
typically defines an array of device IDs that it supports. The format
of these structures and the semantics for comparing device IDs are
completely bus-specific. Defining them as bus-specific entities would
sacrifice type-safety, so we keep bus-specific structures around.

这是最常见的例子设备ID结构。一个驱动程序通常定义一个数组记录它支持的设
备ID 。这些结构的格式与设备ID的语义进行比较是完全特定的。它们作为总线
特定的实体将会牺牲类型安全,所以我们保持周围总线特定的结构。

Bus-specific drivers should include a generic struct device_driver in
the definition of the bus-specific driver. Like this:

总线特定的驱动程序在定义中应该包括一个通用结构体device_driver,如下:

struct pci_driver {
       const struct pci_device_id *id_table;
       struct device_driver   driver;
};

A definition that included bus-specific fields would look like
(using the eepro100 driver again):

一个包括总线特定字段的定义会像如下这样(再次使用eepro100的驱动):

static struct pci_driver eepro100_driver = {
       .id_table       = eepro100_pci_tbl,
       .driver        = {
  .name  = "eepro100",
  .bus  = &pci_bus_type,
  .probe  = eepro100_probe,
  .remove  = eepro100_remove,
  .suspend = eepro100_suspend,
  .resume  = eepro100_resume,
       },
};

Some may find the syntax of embedded struct initialization awkward or
even a bit ugly. So far, it's the best way we've found to do what we want...

有些人可能发现嵌入式结构的初始化可能有些棘手甚至很不好看。但是目前为止这是
最好的办法来实现我们需要的功能。

Registration
~~~~~~~~~~~~

int driver_register(struct device_driver * drv);

The driver registers the structure on startup. For drivers that have
no bus-specific fields (i.e. don't have a bus-specific driver
structure), they would use driver_register and pass a pointer to their
struct device_driver object.

注册
~~~~~~~~~~~~
int driver_register(struct device_driver * drv);
驱动程序在启动的时候注册结构。对于没有总线字段的驱动程序,他们会用驱动
注册器然后传递一个指针给他们的device_driver结构。


Most drivers, however, will have a bus-specific structure and will
need to register with the bus using something like pci_driver_register.

然而,大多数的驱动程序将有一个特定的总线结构和需要注册总线控制的类似
pci_driver_register

It is important that drivers register their driver structure as early as
possible. Registration with the core initializes several fields in the
struct device_driver object, including the reference count and the
lock. These fields are assumed to be valid at all times and may be
used by the device model core or the bus driver.

重要的是驱动器要尽可能早的注册他们的结构。核心在结构device_driver中初始化
一些字段的注册包括引用计数和锁定。这些字段被认为是在任何时候都有效,并可能
用于设备模型核心或总线驱动。

Transition Bus Drivers
~~~~~~~~~~~~~~~~~~~~~~

By defining wrapper functions, the transition to the new model can be
made easier. Drivers can ignore the generic structure altogether and
let the bus wrapper fill in the fields. For the callbacks, the bus can
define generic callbacks that forward the call to the bus-specific
callbacks of the drivers.

总线驱动的转变
~~~~~~~~~~~~~~
在定义包装函数时,到新模式的转变可以更容易的实现。驱动程序可以完全忽视
语类结构然后让总线包装器填写字段。对于回调,总线可以定义类的回调,将呼
叫传送到总线特定驱动的回调。

This solution is intended to be only temporary. In order to get class
information in the driver, the drivers must be modified anyway. Since
converting drivers to the new model should reduce some infrastructural
complexity and code size, it is recommended that they are converted as
class information is added.

该解决方案的目的只是暂时的。为了得到驱动程序中类的信息,驱动程序必须被
修改。驱动程序转变到新模式应该减少一些基础结构的复杂性和代码大小,建议
说它们被转换为添加类的信息。

Access
~~~~~~

Once the object has been registered, it may access the common fields of
the object, like the lock and the list of devices.

访问
~~~
一旦对象已经被注册,它可以访问的公共字段的对象,就像锁和设备的名单。

int driver_for_each_dev(struct device_driver * drv, void * data,
          int (*callback)(struct device * dev, void * data));

    
The devices field is a list of all the devices that have been bound to
the driver. The LDM core provides a helper function to operate on all
the devices a driver controls. This helper locks the driver on each
node access, and does proper reference counting on each device as it
accesses it.

设备字段是所有绑定到驱动程序上设备的名单。LDM核心提供了一个帮助函数来
操作一个驱动程序控制的所有设备。这个助手锁在驱动程序上每一个访问节点上,
而且当它访问每一个设备时做适当的引用计数。

sysfs
~~~~~

When a driver is registered, a sysfs directory is created in its
bus's directory. In this directory, the driver can export an interface
to userspace to control operation of the driver on a global basis;
e.g. toggling debugging output in the driver.

sysfs虚拟文件系统
~~~~~~~~~~~~~~~~~
当驱动程序被注册,在总线目录中创建了一个sysfs的目录。在此目录中,驱动程序
可以输出一个在全球基础的上用户空间到驱动的控制操作;例如在驱动程序中切换
调试输出。

A future feature of this directory will be a 'devices' directory. This
directory will contain symlinks to the directories of devices it
supports.

这个目录未来的功能将是一个'设备'目录。这目录将包含它所支持的设备目录符号
链接。

Callbacks
~~~~~~~~~

 int (*probe) (struct device * dev);

The probe() entry is called in task context, with the bus's rwsem locked
and the driver partially bound to the device.  Drivers commonly use
container_of() to convert "dev" to a bus-specific type, both in probe()
and other routines.  That type often provides device resource data, such
as pci_dev.resource[] or platform_device.resources, which is used in
addition to dev->platform_data to initialize the driver.

回调
~~~~~
    int (*probe) (struct device * dev);

probe()的入口叫做任务的上下文,与总线的rwsem锁定兵器驱动程序部分绑定在设备
上。在probe()和别的常规中,驱动程序通常用container_of()把“dev”转换成特定总
线类型。这种类型往往提供的设备资源数据,像pci_dev.resource[] 或者
platform_device.resources,被用于除dev->platform_data之外的驱动程序初始化
中。

This callback holds the driver-specific logic to bind the driver to a
given device.  That includes verifying that the device is present, that
it's a version the driver can handle, that driver data structures can
be allocated and initialized, and that any hardware can be initialized.
Drivers often store a pointer to their state with dev_set_drvdata().
When the driver has successfully bound itself to that device, then probe()
returns zero and the driver model code will finish its part of binding
the driver to that device.

这个回调保留driver-specific的逻辑性使它绑定到一个得到的设备。这包括验证该
设备存在,它是一个驱动程序能处理的版本,驱动程序的数据结构可以被分配和初始
化,并且任何硬件可以被初始化。驱动程序通常保存一个指向该状态的
dev_set_drvdata()。当驱动程序成功绑定到该设备,然后probe()返回零和驱动模式
代码将完成绑定驱动程序和设备的部分。

A driver's probe() may return a negative errno value to indicate that
the driver did not bind to this device, in which case it should have
released all resources it allocated.

驱动程序的probe()可能会返回一个负的errno值,表明驱动程序没有绑定到设备,
在这种情况下它应该释放它分配到的所有资源。

 int  (*remove) (struct device * dev);

remove is called to unbind a driver from a device. This may be
called if a device is physically removed from the system, if the
driver module is being unloaded, during a reboot sequence, or
in other cases.

remove被称为解除驱动程序与设备的绑定。因为可能在重新启动序列,或在其他情
况下,一个设备被物理的从系统中删除调用,或驱动模块被卸载。

It is up to the driver to determine if the device is present or
not. It should free any resources allocated specifically for the
device; i.e. anything in the device's driver_data field.

驱动程序决定是否存在设备。它应该释放任何资源专门用于分配给设备;即在设
备的driver_data字段的任何成员。

If the device is still present, it should quiesce the device and place
it into a supported low-power state.

如果该设备仍然存在,它应该静止设备且将它带入低能耗状态。

 int (*suspend) (struct device * dev, pm_message_t state);

suspend is called to put the device in a low power state.

suspend使设备进入低能耗状态。

 int (*resume) (struct device * dev);

Resume is used to bring a device back from a low power state.

resume使设备解除低能耗状态。

Attributes
~~~~~~~~~~
属性
~~~~

struct driver_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device_driver *driver, char *buf);
        ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
};

Device drivers can export attributes via their sysfs directories.
Drivers can declare attributes using a DRIVER_ATTR macro that works
identically to the DEVICE_ATTR macro.

设备驱动程序可以经过他们的sysfs目录输出属性。驱动程序可以使用DRIVER_ATTR
宏声明相同作用的DRIVER_ATTR宏。

Example:

DRIVER_ATTR(debug,0644,show_debug,store_debug);

This is equivalent to declaring:

struct driver_attribute driver_attr_debug;

This can then be used to add and remove the attribute from the
driver's directory using:

int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);

例如:
DRIVER_ATTR(debug,0644,show_debug,store_debug);

这等于宣告:
struct driver_attribute driver_attr_debug;

这可以使用驱动程序的目录来添加和删除属性:
int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值