PCI设备编号

参考理解文档:https://wenku.baidu.com/view/23335dd349649b6648d747bf.html

1.PCI设备编号

每一个PCI device都有其unique PFA(PCI Fcntion Address)
PFA由 bus number、device number、function number组成

一条PCI总线支持256个PFA,即支持256个PCI device

每个PCI芯片都有自己的device number(取决于IDSEL管脚),每个PCI芯片占用8个PFA。

每个PCI芯片的第一个PCI device的PFA必为8的倍数。

若PCI device的配置空间中PCI_HEADER_TYPE寄存器的最高bit为1,说明此芯片还有其他PFA,即还有其他device,即当前芯片是

multi-function device.
    Each function on a multi-function device has its own configuration space

在系统中,每个PCI芯片上的所独有的信号线是:INTA、INTB、INTC、INTD、IDSEL

每个芯片上的IDSEL需要连到PCI总线中AD[31:11]中的一根,这对应于PCI device PFA的device number

IDSEL is equivalent to chip select on the CPU side during address phase of CFG RD\WR command.

DEVSEL is used in every transaction when the target claims the cycle address to it. It is like saying this cycle in mine, and nobody touches it!

pci引脚定义连接
https://wenku.baidu.com/view/62606b17e2bd960590c677c3.html

2.PCI配置空间

每个PCI逻辑设备都有自己的配置空间,里面存储了一些基本信息,生产商,IRQ中断号,还有就是定义了mem空间和io空间的起始地址和大小。
在这里插入图片描述
CPU通过两个寄存器访问PCI设备的配置空间:CFG_ADDR 和 CFG_DATA。
在这里插入图片描述
在这里插入图片描述
对CFG_DATA的操作就是对配置空间相应寄存器的操作,没有专门的bit来制定操作类型r/w

PCI配置空间中的BAR(Base Address Register)用来映射PCI设备的寄存器,里面的值是bus地址首地址,至于空间的大小,先向bar中写0xFFFFFFFFF,然后读取,选最低的一位非0的,比如为0x1000,那个空间的大小就为0x1000。

这里需要注意,当PCI配置成64bit或32bit时,BAR有区别
在这里插入图片描述

3.PCI地址转换

当CPU访问PCI设备的mem空间和io空间的寄存器时,需要进行地址转换。
MPC8560有5个outbound窗口0~5用来将CPU内部地址转换为PCI总线地址。上电时只有窗口0使能的,其他都是disable状态。每个outbound窗口有如下三类寄存器:
1.外部PCI总线地址的基址
2.CPU内部32bit地址的基址(EA)
3.窗口属性寄存器,大小、转换类型等等

outbound窗口转换后(外部PCI总线地址的基址,当使用64bit PCI时会用到第二个扩展寄存器)
在这里插入图片描述
在这里插入图片描述
outbound窗口转换前地址(CPU内部32bit地址的基址)
在这里插入图片描述

outbound窗口属性寄存器
在这里插入图片描述
EN:设置此窗口是否使能
RTT/WTT:分别设置此窗口的存取方式(memory或io)
OWS:设置此窗口大小

同理,当PCI设备访问MPC8560时,有3个inbound窗口1~3用来将PCI总线地址转换为CPU内部地址。和outbound窗口一样,inbound窗口有如下三类寄存器
CPU内部32bit地址的基址(EA)
外部PCI总线地址的基址
窗口属性寄存器,大小、转换类型等等
在这里插入图片描述
EN:设置此窗口是否使能
PF:设置此窗口是否开启prefetchable特性
TGI:Target Interface,见datasheet P883
RTT/WTT:设置PCI外设访问CPU时的存取方式(snoop L2cache 等等)
IWA:设置此窗口的大小

3.PCI拓扑结构

PCI拓扑结构,有如下例子
在这里插入图片描述
在上图的总线结构中,ethernet设备和pci-pci bridge的资源空间必须要是pci bus0的一个子集
同理,SCSI和VIDEO同类型资源必须要是pci_bus1的子集。

CPU访问PCI的过程是这样的(只有一个根总线和pci-pci bridge过滤窗口功能打开的情况):
1.cpu向pci发出一个I/O请求。
首先经过根总线.它会判断是否在它的资源范围内.如果在它的范围,它就会丢向总线所在的每一个设备.包括pci bridge. 如果没有在根总线的资源范围,则不会处理这个请求.
2.如果pci设备判断该地址属于它的资源范围,则处理后发出应答
3.pci bridge接收到这个请求,它会判断I/O地址是否在它的资源范围内.如果在它的范围,它会把它丢到它的下层子线.
4.下层总线经过经过相同的处理后,就会找到这个PCI设备了

一个PCI设备访问其它PCI设备或者其它外设的过程:
1.首先这个PCI发出一个请求,这个请求会在总线上广播
2.如果要请求的设备是在同级总线,就会产生应答
3.请求的设备不是在同层总线,就会进行pci bridge.pci桥判断该请求不在它的范围内(目的地不是它下层的设备),就会将它丢向上层
4.这样辗转之后,就能找到对应的设备了

3.PCI枚举过程

通过PCI枚举,CPU知道当前系统上有多少PCI设备,多少根PCI总线,PCI配置空间初始化

PCI 总线扫描的原理是从总线 0 扫描到总线 255,对于每条总线,系统都会扫描所有(总线号,设备号,功能号),读出每个设备配置空间的Device ID和Vendor ID寄存器,如果这两个寄存器的值是个无效值(0xFFFF),则说明当前位置上没有设备,接着扫描下一个位置

如果是有效值(非0xFFFF),当前位置是个有效的 PCI 设备/桥。进而再读取该设备的 Header Type 寄存器,如果该寄存器为 1,则表示当前设备是 PCI 桥,否则是 PCI 设备

Register Number:配置空间寄存器偏移量
Function Number:多功能设备有多个功能号
Device Number:设备编号
Bus Number:总线编号
在这里插入图片描述
对所有 PCI 总线进行编号:
PCI 桥如何知道它所连接的 PCI 总线情况呢?这就需要对 PCI 桥进行总线编号。前面介绍过 PCI 桥提供了 Primary Bus Number、Secondary Bus Number 和 Subordinate Bus Number 三个寄存器用于标志该桥所连接的 PCI 总线,下面通过一个示例来说明内核对于 PCI 总线是如何进行编号的。
在这里插入图片描述
1.系统运行初始,Bus A 为 0,通过上面的 PCI 总线扫描得到连接在 Bus A 上的 PCI 桥(即图中Bridge 1)
2.下面开始设置 Bridge 1 的 Bus 寄存器。将 Primary Bus Number 寄存器设置成 Bus A 的编号,即 0。将 Secondary Bus Number 寄存器设置成 Bus B 的编号,它的值等于(Bus A + 1),也就是 1。由于暂时无法知道该桥所能访问的所有下行总线数目,Subordinate Bus Number 寄存器暂时设置成 0xFF
3.当扫描完所有 Bus A 上所有(设备号,功能号)后,开始扫描 Bus B,Bus B 的编号在扫描完 Bus A 后已经得到,为 1。Bus B 的扫描方法同步骤(1),先扫描出 Bus B 上的 PCI 桥(即图中的 Bridge 2),然后配置 Primary Bus Number 寄存器为 1,Secondary Bus Number 寄存器为 2,而 Subordinate Bus Number 寄存器依然为 0xFF。
4.Bus B 扫描完后得到 Bus C 的编号,为2。下面开始扫描 Bus C,因为 Bus C 上没有 PCI 桥,于是在扫描完其它(设备号,功能号)后,Bus C 的扫描结束
5.由于 Bridge 2 所能访问到的最大 Bus 编号是 2,因此重新设置 Bridge 2 的 Subordinate Bus Number 寄存器为 2。
6.由于 Bridge 1 所能访问到的最大 Bus 编号也是 2,因此重新设置 Bridge 1 的 Subordinate Bus Number 寄存器为 2。
7.总线编号结束

3.Linux内核PCI数据结构.

内核(linux-2.6.24) 提供了三类数据结构用以描述 PCI 控制器、PCI 设备以及 PCI 总线。
数据结构关系如下所示
在这里插入图片描述
PCI 控制器 用 pci_controller 结构来描述,它有以下几个主要的属性:
index:该属性标志 PCI 控制器的编号。
next:该属性指向下一个 PCI 控制器,通过 next 属性,PCI 控制器可以形成一个单向链表。
first_busno:该属性标志了连接在该控制器上第一条总线的编号。
last_busno:该属性标志了连接在该控制器上最后一条总线的编号。
ops:该属性标志了当前 PCI 控制器所对应的 PCI 配制空间读写操作函数。
io_space:该属性标志了当前 PCI 控制器所支持的 IO 地址空间。
mem_space:该属性标志了当前 PCI 控制器所支持的 Memory 地址区间。
cfg_addr:该属性标志了当前 PCI 控制器发起 Configuration 访问方式时所需要写入的地址空间。
cfg_data:该属性标志了当前 PCI 控制器发起 Configuration 访问方式时所需要读写的数据空间。
bus:该属性标志了当前 PCI 控制器所连接的 PCI 总线,它对应的数据结构是 pci_bus。

PCI 总线 用 pci_bus 结构来描述,它有以下几个主要的属性:
parent:可通过该属性索引到上层 PCI 总线。
self:该属性标志了连接的上行 PCI 桥(对应的数据结构是 pci_dev)。
children:该属性标志了总线连接的所有 PCI 子总线链表。
devices:该属性标志了总线连接的所有 PCI 设备链表。
ops:该属性标志了总线上所有 PCI 设备的配制空间读写操作函数。
number:该属性标志了当前 PCI 总线的编号。
primary:该属性标志了 PCI 上行总线编号。
secondary:该属性标志了 PCI 下行总线编号。
subordinate:该属性标志了能够访问到的最大总线编号。
resource:该属性标志了 Memory/IO 地址空间

PCI 设备 用 pci_dev 结构来描述,它有以下几个主要的属性:
global_list:Linux 定义了一个全局列表来索引所有PCI 设备,该属性标志了这个全局列表的首指针。
bus:该属性标志了当前设备所在的 PCI 总线(对应的数据结构是 pci_bus)。
devfn:该属性标志了设备编号和功能编号。
vendor:该属性标志了供应商编号。
device:该属性标志了设备编号。
driver:该属性标志了设备对应的驱动代码(对应的数据结构是 pci_driver)。
irq:该属性标志了中断号。
resource:该属性标志了 Memory/IO 地址区间

当 Linux 内核在做 PCI 初始化工作时,它会根据建立一个由 pci_controller、pci_bus 和 pci_dev 三者组成的一个组织结构图。根据这个结构,软件开发者可以很方便的通过 PCI 控制器索引到每个 PCI 设备或者 PCI 总线

4.Linux的PCI子系统初始化流程

第一步:Linux分配数据结构pci_contoller,并初始化,包括PCI的mem/io空间范围和访问PCI配置空间所需的handler。
第二步:PCI设备的枚举:扫描系统上所有PCI设备,初始化它们的配置空间。(硬件上的初始化)
第三步:用数据结构将PCI设备信息联系起来,构建PCI树。(软件上的初始化)
第四步:加载PCI设备驱动

4.1 初始化PCI控制器

pci_controller结构是内核描述PCI子系统信息的数据结构,里面定义了可供PCI设备使用的mem资源和io资源的范围,访问pci设备配置空间的handler等等。
函数调用关系:
start_kernel --> mpc8560ads_setup_arch --> mpc85xx_setup_hose()
此函数分配并初始化了pci_controller
mpc85xx_setup_hose()
–>pcibios_alloc_controller() //分配数据结构pci_controller
ppc_md.pci_map_irq = mpc85xx_map_irq; //用来获得pci设备irq号的handler
–>setup_indirect_pci() //设置pci_controller里访问PCI配置空间的钩子函数
//使用ioremap后的CFG_ADDR和CFG_DATA的虚拟地址
–>mpc85xx_setup_pci1() //设置PCI inbound和outbound窗口寄存器

PCI子系统的mem和io地址空间范围也在函数mpc85xx_setup_hose()中定义:
pci_controller *hose_a;
hose_a->mem_space.start = MPC85XX_PCI1_LOWER_MEM;
hose_a->mem_space.end = MPC85XX_PCI1_UPPER_MEM;
hose_a->io_space.start = MPC85XX_PCI1_LOWER_IO;
hose_a->io_space.end = MPC85XX_PCI1_UPPER_IO;

4.2 PCI枚举过程

目前为止,内核只知道PCI子系统总的mem资源和io资源地址范围。
接下来,内核需要扫描所有PCI设备,把这些资源分配给PCI设备,具体方法参考前面讲的PCI枚举过程。

内核分配mem资源时是从高地址开始分配的。

mpc85xx_setup_hose()
    -->pciauto_bus_scan()
    for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {    //遍历0号总线上所有PCI设备
        if (读当前设备配置空间PCI_HEADER_TYPE失败)
            continue;                        //当前设备不存在,扫描下一个
        读当前设备配置空间PCI_CLASS_REVISION
        If(当前设备是PCI桥){
            pciauto_setup_bars()            //分配pci_controller的资源的子集
            pciauto_prescan_setup_bridge()      //写PCI桥配置空间 PCI_PRIMARY_BUS
                                                //PCI_SECONDARY_BUS
                                                //PCI_SUBORDINATE_BUS
            pciauto_bus_scan()                        //递归扫描下一条pci bus
            pciauto_postscan_setup_bridge()            //写PCI桥配置空间PCI_SUBORDINATE_BUS
        }
        。。。。。略去
        else {
            //当前设备是PCI设备
            pciauto_setup_bars()
        }
    }

注意:执行完 pciauto_bus_scan后,所有pci设备(包括桥)的配置空间都已经傻瓜式的简单初始化
但这些桥和设备还没有通过数据结构组织起来,这些工作要在第四步 pcibios_init里来完成

4.3 创建PCI树

上面说了,PCI设备配置空间都初始化差不多了,但是PCI设备还没有通过数据结构组织起来。

上面说了,PCI设备配置空间都初始化差不多了,但是PCI设备还没有通过数据结构组织起来。   

do_initcalls()
    -->pcibios_init()    //所在文件 arch/ppc/kernel/pci.c

pcibios_init()   
    1):为PCI设备构造数据结构,组织成PCI树
    -->pci_scan_bus(hose->first_busno, hose->ops, hose)    //hose就是上面的pci_controller结构
        -->pci_scan_bus_parented
            -->pci_create_bus        // 建立 PCI bus 0 对应的数据结构,这个bus的资源尚未初始化
            -->pci_scan_child_bus    // 从PCI bus 0 开始扫描生成PCI树,使用了递归
                -->pci_scan_slot
                    -->pci_scan_single_dev
                        -->pci_scan_device()    //创建 pci_dev结构
                            -->pci_setup_device()    //区分桥与设备,分别进行初始化
                                -->pci_read_bases();    //在这才初始化了pci_dev->resource[]

pci_dev->resouce[]中保存的才是cpu internal address(EA),可以对这些地址进行用ioremap,在驱动程序对bar所指位置读写的时候一定要用这个

(2)给PCI设备分配IRQ号

-->pci_fixup_irqs()
        //遍历所有pci设备,调用pdev_fixup_irq()
        -->pdev_fixup_irq
            -->ppc_md.pci_swizzle()     //实际调用common_swizzle(),获得pci所在slot编号
            读PCI设备配置空间PCI_INTERRUPT_PIN,获得中断pin编号[14]
            之所以是14,因为PCI规范里设备最多4个管脚(除第一个外,其他3个仅用于多功能设备)
            -->ppc_md.pci_map_irq() //实际调用mpc85xx_map_irq()
                                    //根据slot,pin  pci_irq_table[][4]
                                    //来计算出irq号
            -->pcibios_update_irq(pci_dev,irq)
              //将irq号写入pci设备的配置空间PCI_INTERRUPT_LINE
              //注意,这里寄存器只是用来保存结果,例如把其值8改为9,并不能改变中断号

(3)PCI结构树有了,现在构建PCI的资源树,有冲突就修改

 -->pcibios_allocate_bus_resource()
        //只考虑pci_bus,形成bus级资源树(并同时check,资源冲突了就修改)
    -->pcibios_allocate_resources()
        //把pci_dev也考虑进去,完成资源树
4.3 加载PCI设备驱动

以e1000 PCI 网卡 82546GB为例,讲解一个PCI驱动的加载过程
驱动里有如下代码;

static struct pci_driver e1000_driver = {
    .name     = e1000_driver_name,
    .id_table = e1000_pci_tbl,
    .probe    = e1000_probe,
    .remove   = __devexit_p(e1000_remove),
#ifdef CONFIG_PM
    /* Power Managment Hooks */
    .suspend  = e1000_suspend,
    .resume   = e1000_resume,
#endif
    .shutdown = e1000_shutdown,
    .err_handler = &e1000_err_handler
};

module_init(e1000_init_module);
do_initcalls()
    -->e1000_init_module
        pci_register_driver(&e1000_driver)
        // e1000_driver.driver.bus = &pci_bus_type;
    -->driver_register(e1000_driver.driver);
    //pci_bus_type.probe() 非空,即调用pci_device_probe()

pci_device_probe(*device)
    -->__pci_device_probe(*pci_driver,*pci_dev)
        -->pci_match_device(*pci_driver,*pci_dev)
        -->pci_call_probe(*pci_driver,*pci_dev,pci_device_id)
            -->drv->probe(*pci_device,*pci_device_id)
            即执行 e1000_probe(*pci_device,*pci_device_id)

接下来就是e1000 PCI 网卡驱动的具体代码。
  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LINUX设备驱动第三版_ 前言 第一章 设备驱动程序简介 设备驱动程序的作用 内核功能划分 设备和模块的分类 安全问题 版本编号 许可证条款 加入内核开发社团 本书概要 第二章 构造和运行模块 设置测试系统 Hello World模块 核心模块与应用程序的对比 编译和装载 内核符号表 预备知识 初始化和关闭 模块参数 在用户空间编写驱动程序 快速参考 第三章 字符设备驱动程序 scull的设计 主设备号和次设备号 一些重要的数据结构 字符设备的注册 open和release scull的内存使用 read和write 试试新设备 快速参考 第四章 调试技术 内核中的调试支持 通过打印调试 通过查询调试 通过监视调试 调试系统故障 调试器和相关工具 第五章 并发和竞态 scull的缺陷 并发及其管理 信号量和互斥体 completion 自旋锁 锁陷阱 除了锁之外的办法 快速参考 第六章 高级字符驱动程序操作 ioctl 阻塞型I/O poll和select 异步通知 定位设备 设备文件的访问控制 快速参考 第七章 时间、延迟及延缓操作 度量时间差 获取当前时间 延迟执行 内核定时器 tasklet 工作队列 快速参考 第八章 分配内存 kmalloc函数的内幕 后备高速缓存 get_free_page和相关函数 vmalloc及其辅助函数 per-CPU变量 获取大的缓冲区 快速参考 第九章 与硬件通信 I/O端口和I/O内存 使用I/O端口 I/O端口示例 使用I/O内存 快速参考 第十章 中断处理 准备并口 安装中断处理例程 实现中断处理例程 顶半部和底半部 中断共享 中断驱动的I/O 快速参考 第十一章 内核的数据类型 使用标准C语言类型 为数据项分配确定的空间大小 接口特定的类型 其他有关移植性的问题 链表 快速参考 第十二章 PCI驱动程序 PCI接口 ISA回顾 PC/104和PC/104+ 其他的PC总线 SBus NuBus 外部总线 快速参考 第十三章 USB驱动程序 USB设备基础 USB和Sysfs USB urb 编写USB驱动程序 不使用urb的USB传输 快速参考 第十四章 Linux设备模型 kobject、kset和子系统 低层sysfs操作 热插拔事件的产生 总线、设备和驱动程序 类 各环节的整合 热插拔 处理固件 快速索引 第十五章 内存映射和DMA Linux的内存管理 mmap设备操作 执行直接I/O访问 直接内存访问 快速参考 第十六章 块设备驱动程序 注册 块设备操作 请求处理 其他一些细节 快速参考 第十七章 网络驱动程序 snull设计 连接到内核 net_device结构细节 打开和关闭 数据包传输 数据包的接收 中断处理例程 不使用接收中断 链路状态的改变 套接字缓冲区 MAC 地址解析 定制 ioctl 命令 统计信息 组播 其他知识点详解 快速参考 第十八章 TTY驱动程序 小型TTY驱动程序 tty_driver函数指针 TTY线路设置 ioctls proc和sysfs对TTY设备的处理 tty_driver结构详解 tty_operations结构详解 tty_struct结构详解 快速参考 参考书目 9112405-1_o.jpg (85.53 KB, 下载次数: 50)
内容简介 《LINUX设备驱动程序(第3版)》已针对Linux内核的2610版本彻底更新过了。内核的这个版本针对常见任务完成了合理化设计及相应的简化,如即插即用、利用sysfs文件系统和用户空间交互,以及标准总线上的多设备管理等等。要阅读并理解本书,您不必首先成为内核黑客;只要您理解C语言并具有Unix系统调用的一些背景知识即可。您将学到如何为字符设备、块设备和网络接口编写驱动程序。为此,《LINUX设备驱动程序(第3版)》提供了完整的示例程序,您不需要特殊的硬件即可编译和运行这些示例程序。《LINUX设备驱动程序(第3版)》还在单独的章节中讲述了PCI、USB和tty(终端)子系统。对期望了解操作系统内部工作原理的读者来讲,《LINUX设备驱动程序(第3版)》也深入阐述了地址空间、异步事件以及I/O等方面的内容。 作者简介 作者:(美)科波特 译者:魏永明 耿岳 钟书毅 Jonahan Corbet早在1981年就开始接触BSD Unix的源代码。那时,科罗拉多大学的一名讲师让他“修正”其中的分页算法。从那时起直到现在。他深入研究了他所遇到的每一个系统,其中包括VAX、Sun、Arden以及x86系统的驱动程序。他在1993年第一次接触Linux系统,从此以后一直从事Linux的开发。Corbet先生是《Linux Weekly News》的创始人和执行主编。他和妻子及两个孩子生活在科罗多州的玻尔得市。 目录 ch00.前言 ch01.第一章 设备驱动程序简介 设备驱动程序的作用 内核功能划分 设备和模块的分类 安全问题 版本编号 许可证条款 加入内核开发社团 本书概要 ch02.第二章 构造和运行模块 设置测试系统 Hello world模块 核心模块与应用程序的对比 编译和装载 内核符号表 预备知识 初始化和关闭 模块参数 在用户空间编写驱动程序 快速参考 ch03.第三章 字符设备驱动程序 scull的设计 主设备号和次设备号 一些重要的数据结构 字符设备的注册 open和release scull的内存使用 read和write 试试新设备 快速参考 ch04.第四章 调试技术 内核中的调试支持 通过打印调试 通过查询调试 通过监视调试 调试系统故障 调试器和相关工具 ch05.第五章 并发和竞态 scull的缺陷 并发及其管理 信号量和互斥体 completiOn 自旋锁 锁陷阱 除了锁之外的办法 快速参考 ch06.第六章 高级字符驱动程序操作 ioctl 阻塞型I/O poll和select 异步通知 定位设备 设备文件的访问控制 快速参考 ch07.第七章 时间、延迟及延缓操作 度量时间差 获取当前时间 延迟执行 内核定时器 tasklet 工作队列 快速参考 ch08.第八章 分配内存 kmalloc函数的内幕 后备高速缓存 get—free—page和相关函数 vmalloc及其辅助函数 per-CPU变量 获取大的缓冲区 快速参考 ch09... ch10... ... ch18...
WinRing PCI寄存器是一个PCI总线工具,用于读取和修改计算机系统中的PCI设备配置信息。 PCI(Peripheral Component Interconnect,外围元件互连)总线是一种计算机外部设备与主机之间的连接接口标准。每个PCI设备都有一个唯一的设备编号和相关的配置寄存器,用于存储设备的相关信息,如设备厂商和型号、设备类型、硬件功能和性能等。 WinRing是一种用于访问和管理PCI设备寄存器的工具,它提供了一种简化的接口,使用户能够快速的读取和设置PCI设备的配置信息。通过WinRing,用户可以实时监测PCI设备的状态、性能和错误信息,并调整设备的工作参数。这对于系统管理员和硬件工程师来说是非常重要的,他们可以通过WinRing更好地了解和管理系统中的PCI设备。 使用WinRing,用户可以执行以下操作: 1. 查看PCI设备信息:包括设备编号、厂商ID、设备ID、子系统ID等信息,了解设备的基本特性。 2. 修改PCI设备配置:可以对PCI设备的配置寄存器进行读取和修改,例如调整设备的时钟频率、中断设置等。 3. 监控PCI设备性能:通过监控寄存器的值,可以实时了解设备的工作状态、传输速率等性能参数。 4. 检测和诊断PCI设备错误:可以检测和记录PCI设备的错误状态和错误码,帮助用户快速诊断和解决问题。 总之,WinRing PCI寄存器是一个方便实用的工具,提供了读取和修改计算机系统中PCI设备配置信息的功能,用于优化和管理PCI设备的使用。同时,它也是一个有力的诊断工具,可以帮助用户快速发现和解决PCI设备相关的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值