一些 PCI 配置寄存器是要求的, 一些是可选的. 每个 PCI 设备必须包含有意 义的值在被要求的寄存器中, 而可选寄存器的内容依赖外设的实际功能. 可选的字段不被 使用, 除非被要求的字段的内容指出它们是有效的. 因此, 被要求的字段声称板的功能, 包括其他的字段是否可用.

注意 PCI 寄存器一直是小端模式. 尽管标准被设计为独立于体系, PCI 设计者有时露出 一些倾向 PC 环境. 驱动编写者应当小心处理字节序, 当存取多字节配置寄存器时; 在 PC 上使用的代码可能在其他平台上不工作. Linux 开发者已经处理了这个字节序问题(见 下一节, "存取配置空间"), 但是这个问题必须记住. 如果你曾需要转换数据从主机序到 PCI 序, 或者反之, 你可求助在 <asm/byteorder.h> 中定义的函数, 在第 11 章介绍, 知道 PCI 字节序是小端.

描述所有的配置项超出了本书的范围. 常常地, 随每个设备发布的技术文档描述被支持的 寄存器. 我们感兴趣的是一个驱动如何能知道它的设备以及它如何能存取设备的配置空间.

3 个或者 4 个 PCI 寄存器标识一个设备: verdorID, deviceID, 和 class 是 3 个常常 用到的. 每个 PCI 制造商分配正确的值给这些只读寄存器, 并且驱动可使用它们来查找 设备. 另外, 字段 subsystem verdorID 和 subsystem deviceID 有时被供应商设置来进 一步区分类似的设备.

我们看这些寄存器的细节: vendorID

这个 16-位 寄存器标识一个硬件制造商. 例如, 每个 Intel 设备都标有相同的供 应商号, 0x8086. 这样的号有一个全球的注册, 由 PCI 特别利益体所维护, 并且 供应商必须申请有一个唯一的分配给它们的号.

deviceID

这是另一个 16-位 寄存器, 由供应商选择; 对于这个设备 ID 没有要求官方的注 册. 这个 ID 常常和 供应商 ID 成对出现来组成一个唯一的 32-位 标识符给一个 硬件设备. 我们使用词语"签名"来指代供应商和设备 ID 对. 一个设备驱动常常依 靠签名来标识它的设备; 你可在硬件手册中找到对于目标设备要寻找的值.

class

每个外设都属于一个类. 类寄存器是一个 16-位 值, 它的高 8 位标识"基类"(或 者群). 例如, "ethernet"和"token ring"是 2 个类都属于"network"群, 而 "serial"和"parallel"属于"communication"群. 一些驱动可支持几个类似的设备, 每个都有一个不同的签名但是都属于同样的类; 这些驱动可依赖类寄存器标识它们 的外设, 就象后面所示.

subsystem vendorID subsystem deviceID

这些字段可用来进一步标识一个设备. 如果芯片对于本地总线是一个通用接口芯片, 它常常被用在几个完全不同的地方, 并且驱动必须标识出它在与之通话的实际设备. 子系统标志用作此目的.

使用这些不同的标识符, 一个 PCI 驱动可告知内核它支持什么类型的设备. struct pci_device_id 结构被用来定义一个驱动支持的不同类型 PCI 设备的列表. 这个结构包 含不同的成员:

u32 vendor;

u32 device;

这些指定一个设备的 PCI 供应商和设备 ID. 如果驱动可处理任何供应商或者设备 ID, 值 PCI_ANY_ID 应当用作这些成员上.

u32 subvendor;

u32 subdevice;

这些指定一个设备的 PCI 子系统供应商和子系统设备 ID. 如果驱动可处理任何类 型的子系统 ID, 值 PCI_ANY_ID 应当用作这些成员上.

u32 class;

u32 class_mask;

这 2 个值允许驱动来指定它支持一类 PCI 类设备. 不同的 PCI 设备类( 一个 VAG 控制器是一个例子 )在 PCI 规范里被描述. 如果一个驱动可处理任何子系统 ID, 值 PCI_ANY_ID 应当用作这些字段.

kernel_ulong_t driver_data;

这个值不用来匹配一个设备, 但是用来持有信息, PCI 驱动可用来区分不同的设备, 如果它想这样.

有 2 个帮助宏定义应当被用来初始化一个 struct pci_device_id 结构: PCI_DEVICE(vendor, device)

这个创建一个 struct pci_device_id , 它只匹配特定的供应商和设备 ID. 这个 宏设置这个结构的子供应商和子设备成员为 PCI_ANY_ID.

PCI_DEVICE_CLASS(device_class, device_class_mask)

这个创建一个 struct pci_device_id, 它匹配一个特定的 PCI 类. 一个使用这些宏来定义一个驱动支持的设备类型的例子, 在下面的内核文件中可找到:

drivers/usb/host/ehci-hcd.c:

static const struct pci_device_id pci_ids[] = { {

/* handle any USB 2.0 EHCI controller */

PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),

.driver_data = (unsigned long) &ehci_driver,

},

{ /* end: all zeroes */ }

};

drivers/i2c/busses/i2c-i810.c:

static struct pci_device_id i810_ids[] = {

{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },

{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },

{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },

{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },

{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },

{ 0, },

};

这些例子创建一个 struct pci_device_id 结构的列表, 列表中最后一个是被设置为全零 的的空结构. 这个 ID 的数组用在 struct pci_driver (下面讲述), 并且它还用来告诉 用户空间这个特定的驱动支持哪个设备.

Linux 内核 标准 PCI 配置寄存器的更多相关文章

  1. linux内核编译环境配置

    linux内核编译环境配置 如果不是编译内核,只需要安装与内核相匹配的kernel-devel开发包即可.即是/lib/modules/`uname -r`/build -> /usr/src/ ...

  2. linux内核编译,配置本机驱动

    1.前言  编译linux内核失败的原因很多时候就是驱动选错,适合自己本机的驱动没编译进去.面对特殊平台(或者有些洁癖者,我就是^_^),要编译精简内核,只要本机驱动,其他都不需要.面对内核里面这么多 ...

  3. linux内核源代码、配置与编译

    内核源代码下载:www.kernel.org Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具可读性. linux内核代码最好不要在windows ...

  4. Linux 内核USB 接口配置

    USB 接口是自己被捆绑到配置的. 一个 USB 设备可有多个配置并且可能在它们之间转换 以便改变设备的状态. 例如, 一些允许固件被下载到它们的设备包含多个配置来实现这个. 一个配置只能在一个时间点 ...

  5. 云服务器-Ubuntu更新系统版本-更新Linux内核-服务器安全配置优化-防反弹shell

    购入了一台阿里云的ESC服务器,以前都用CentOS感觉Yum不怎么方便,这次选的Ubuntu16.04.7 搭好服务之后做安全检查,发现Ubuntu16.04版本漏洞众多:虽然也没有涉及到16.04 ...

  6. Linux内核配置、编译及Makefile简述

    Hi,大家好!我是CrazyCatJack.最近在学习Linux内核的配置.编译及Makefile文件.今天总结一下学习成果,分享给大家^_^ 1.解压缩打补丁 首先是解压缩你获取到的Linux内核. ...

  7. Linux内核同步

    Linux内核剖析 之 内核同步 主要内容 1.内核请求何时以交错(interleave)的方式执行以及交错程度如何. 2.内核所实现的基本同步机制. 3.通常情况下如何使用内核提供的同步机制. 内核 ...

  8. Linux 内核中的数据结构:基数树(radix tree)

    转自:https://www.cnblogs.com/wuchanming/p/3824990.html   基数(radix)树 Linux基数树(radix tree)是将指针与long整数键值相 ...

  9. [内核同步]浅析Linux内核同步机制

    转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral ...

随机推荐

  1. JasperStudio 输出pdf 出错。

    发表于 2008-09-23 09:35:15 楼主net.sf.jasperreports.engine.JRException: Error retrieving field value from ...

  2. iOS 开发该选择Blocks还是Delegates

    http://www.cocoachina.com/ios/20150925/13525.html 前文:网络上找了很多关于delegation和block的使用场景,发现没有很满意的解释,后来无意中 ...

  3. 自定义连接池DataSourse

    自定义连接池DataSourse 连接池概述: 管理数据库的连接, 作用: 提高项目的性能.就是在连接池初始化的时候存入一定数量的连接,用的时候通过方法获取,不用的时候归还连接即可.所有的连接池必须实 ...

  4. TCPThree_C杯 Day2

    T1 我已经被拉格朗日插值蒙蔽了双眼,变得智障无比. 第一反应就是拉格朗日插值,然后就先放下了它. 模数那么小,指数那么大,这是一套noip模拟题,拉格朗日,你脑袋秀逗了? 无脑暴力20分贼开心. 正 ...

  5. jsp项目中整个项目没有问题但是servlet报错

    项目没问题但是serverlet报错 项目右键 buildPath-->configure build path -->Myeclipse Library-->J2EE 1.3 Li ...

  6. UNP服务器设计范式总结

    一:客户端 本章总结的服务器程序设计范式,使用同一个客户端程序进行测试.个连接.使用的命令如下: client  206.62.226.36  8888  5  500  4000 二:结论 上图测量 ...

  7. MUI - 解决动态列表页图片懒加载再次加载不成功的bug

    首先描述一下功能 实现列表页动态加载 通过官方提供的"下拉刷新和上拉刷新"及"图片懒加载"示例实现. http://www.cnblogs.com/philly ...

  8. Mybatis表关联多对多

    创建表 创建表对应的 JavaBean 对象 package com.tanlei.newer.model; import java.util.List; /** * @author:Mr.Tan * ...

  9. @codeforces - 1214G@ Feeling Good

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n*m 的 01 矩阵 A,一开始所有格子都为 0. ...

  10. SDUT-2133_数据结构实验之栈与队列三:后缀式求值

    数据结构实验之栈与队列三:后缀式求值 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运算符的后缀表示式 ...