diff options
Diffstat (limited to 'Documentation/translations/zh_CN/PCI')
-rw-r--r-- | Documentation/translations/zh_CN/PCI/index.rst | 7 | ||||
-rw-r--r-- | Documentation/translations/zh_CN/PCI/msi-howto.rst | 233 | ||||
-rw-r--r-- | Documentation/translations/zh_CN/PCI/pci-iov-howto.rst | 170 | ||||
-rw-r--r-- | Documentation/translations/zh_CN/PCI/pciebus-howto.rst | 192 | ||||
-rw-r--r-- | Documentation/translations/zh_CN/PCI/sysfs-pci.rst | 126 |
5 files changed, 725 insertions, 3 deletions
diff --git a/Documentation/translations/zh_CN/PCI/index.rst b/Documentation/translations/zh_CN/PCI/index.rst index 5c96017e9f41..16acb2bd9b58 100644 --- a/Documentation/translations/zh_CN/PCI/index.rst +++ b/Documentation/translations/zh_CN/PCI/index.rst @@ -22,13 +22,14 @@ Linux PCI总线子系统 :numbered: pci - -Todolist: - pciebus-howto pci-iov-howto msi-howto sysfs-pci + + +Todolist: + acpi-info pci-error-recovery pcieaer-howto diff --git a/Documentation/translations/zh_CN/PCI/msi-howto.rst b/Documentation/translations/zh_CN/PCI/msi-howto.rst new file mode 100644 index 000000000000..7ea4d50cdad2 --- /dev/null +++ b/Documentation/translations/zh_CN/PCI/msi-howto.rst @@ -0,0 +1,233 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: <isonum.txt> +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/PCI/msi-howto.rst + +:翻译: + + 司延腾 Yanteng Si <siyanteng@loongson.cn> + +:校译: + + + +=========== +MSI驱动指南 +=========== + +:作者: Tom L Nguyen; Martine Silbermann; Matthew Wilcox + +:版权: 2003, 2008 Intel Corporation + +关于本指南 +========== + +本指南介绍了消息标记中断(MSI)的基本知识,使用MSI相对于传统中断机制的优势,如何 +改变你的驱动程序以使用MSI或MSI-X,以及在设备不支持MSI时可以尝试的一些基本诊断方法。 + + +什么是MSI? +========== + +信息信号中断是指从设备写到一个特殊的地址,导致CPU接收到一个中断。 + +MSI能力首次在PCI 2.2中规定,后来在PCI 3.0中得到增强,允许对每个中断进行单独屏蔽。 +MSI-X功能也随着PCI 3.0被引入。它比MSI支持每个设备更多的中断,并允许独立配置中断。 + +设备可以同时支持MSI和MSI-X,但一次只能启用一个。 + + +为什么用MSI? +============ + +有三个原因可以说明为什么使用MSI比传统的基于针脚的中断有优势。 + +基于针脚的PCI中断通常在几个设备之间共享。为了支持这一点,内核必须调用每个与中断相 +关的中断处理程序,这导致了整个系统性能的降低。MSI从不共享,所以这个问题不会出现。 + +当一个设备将数据写入内存,然后引发一个基于引脚的中断时,有可能在所有的数据到达内存 +之前,中断就已经到达了(这在PCI-PCI桥后面的设备中变得更有可能)。为了确保所有的数 +据已经到达内存中,中断处理程序必须在引发中断的设备上读取一个寄存器。PCI事务排序规 +则要求所有的数据在返回寄存器的值之前到达内存。使用MSI可以避免这个问题,因为中断产 +生的写入不能通过数据写入,所以当中断发生时,驱动程序知道所有的数据已经到达内存中。 + +PCI设备每个功能只能支持一个基于引脚的中断。通常情况下,驱动程序必须查询设备以找出 +发生了什么事件,这就减慢了对常见情况的中断处理。有了MSI,设备可以支持更多的中断, +允许每个中断被专门用于不同的目的。一种可能的设计是给不经常发生的情况(如错误)提供 +自己的中断,这使得驱动程序可以更有效地处理正常的中断处理路径。其他可能的设计包括给 +网卡的每个数据包队列或存储控制器的每个端口提供一个中断。 + + +如何使用MSI +=========== + +PCI设备被初始化为使用基于引脚的中断。设备驱动程序必须将设备设置为使用MSI或MSI-X。 +并非所有的机器都能正确地支持MSI,对于这些机器,下面描述的API将简单地失败,设备将 +继续使用基于引脚的中断。 + +加入内核对MSI的支持 +------------------- + +为了支持MSI或MSI-X,内核在构建时必须启用CONFIG_PCI_MSI选项。这个选项只在某些架 +构上可用,而且它可能取决于其他一些选项的设置。例如,在x86上,你必须同时启用X86_UP_APIC +或SMP,才能看到CONFIG_PCI_MSI选项。 + +使用MSI +------- + +大部分沉重的工作是在PCI层为驱动程序完成的。驱动程序只需要请求PCI层为这个设备设置 +MSI功能。 + +要自动使用MSI或MSI-X中断向量,请使用以下函数:: + + int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, + unsigned int max_vecs, unsigned int flags); + +它为一个PCI设备分配最多至max_vecs的中断向量。它返回分配的向量数量或一个负的错误。 +如果设备对最小数量的向量有要求,驱动程序可以传递一个min_vecs参数,设置为这个限制, +如果PCI核不能满足最小数量的向量,将返回-ENOSPC。 + +flags参数用来指定设备和驱动程序可以使用哪种类型的中断(PCI_IRQ_LEGACY, PCI_IRQ_MSI, +PCI_IRQ_MSIX)。一个方便的短语(PCI_IRQ_ALL_TYPES)也可以用来要求任何可能的中断类型。 +如果PCI_IRQ_AFFINITY标志被设置,pci_alloc_irq_vectors()将把中断分散到可用的CPU上。 + +要获得传递给require_irq()和free_irq()的Linux IRQ号码和向量,请使用以下函数:: + + int pci_irq_vector(struct pci_dev *dev, unsigned int nr); + +在删除设备之前,应使用以下功能释放任何已分配的资源:: + + void pci_free_irq_vectors(struct pci_dev *dev); + +如果一个设备同时支持MSI-X和MSI功能,这个API将优先使用MSI-X,而不是MSI。MSI-X支 +持1到2048之间的任何数量的中断。相比之下,MSI被限制为最多32个中断(而且必须是2的幂)。 +此外,MSI中断向量必须连续分配,所以系统可能无法为MSI分配像MSI-X那样多的向量。在一 +些平台上,MSI中断必须全部针对同一组CPU,而MSI-X中断可以全部针对不同的CPU。 + +如果一个设备既不支持MSI-X,也不支持MSI,它就会退回到一个传统的IRQ向量。 + +MSI或MSI-X中断的典型用法是分配尽可能多的向量,可能达到设备支持的极限。如果nvec大于 +设备支持的数量,它将自动被限制在支持的限度内,所以没有必要事先查询支持的向量的数量。:: + + nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) + if (nvec < 0) + goto out_err; + +如果一个驱动程序不能或不愿意处理可变数量的MSI中断,它可以要求一个特定数量的中断,将该 +数量作为“min_vecs“和“max_vecs“参数传递给pci_alloc_irq_vectors()函数。:: + + ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); + if (ret < 0) + goto out_err; + +上述请求类型的最臭名昭著的例子是为一个设备启用单一的MSI模式。它可以通过传递两个1作为 +'min_vecs'和'max_vecs'来实现:: + + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (ret < 0) + goto out_err; + +一些设备可能不支持使用传统的线路中断,在这种情况下,驱动程序可以指定只接受MSI或MSI-X。:: + + nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); + if (nvec < 0) + goto out_err; + +传统API +----------- + +以下用于启用和禁用MSI或MSI-X中断的旧API不应该在新代码中使用:: + + pci_enable_msi() /* deprecated */ + pci_disable_msi() /* deprecated */ + pci_enable_msix_range() /* deprecated */ + pci_enable_msix_exact() /* deprecated */ + pci_disable_msix() /* deprecated */ + +此外,还有一些API来提供支持的MSI或MSI-X向量的数量:pci_msi_vec_count()和 +pci_msix_vec_count()。一般来说,应该避免使用这些方法,而是让pci_alloc_irq_vectors() +来限制向量的数量。如果你对向量的数量有合法的特殊用例,我们可能要重新审视这个决定, +并增加一个pci_nr_irq_vectors()助手,透明地处理MSI和MSI-X。 + +使用MSI时需要考虑的因素 +----------------------- + +自旋锁 +~~~~~~ + +大多数设备驱动程序都有一个每的自旋锁,在中断处理程序中被占用。对于基于引脚的中断 +或单一的MSI,没有必要禁用中断(Linux保证同一中断不会被重新输入)。如果一个设备 +使用多个中断,驱动程序必须在锁被持有的时候禁用中断。如果设备发出一个不同的中断, +驱动程序将死锁,试图递归地获取自旋锁。这种死锁可以通过使用spin_lock_irqsave() +或spin_lock_irq()来避免,它们可以禁用本地中断并获取锁(见《不可靠的锁定指南》)。 + +如何判断一个设备上是否启用了MSI/MSI-X +------------------------------------- + +使用“lspci -v“(以root身份)可能会显示一些具有“MSI“、“Message Signalled Interrupts“ +或“MSI-X“功能的设备。这些功能中的每一个都有一个“启用“标志,后面是“+“(启用) +或“-“(禁用)。 + + +MSI特性 +======= + +众所周知,一些PCI芯片组或设备不支持MSI。PCI协议栈提供了三种禁用MSI的方法: + +1. 全局的 +2. 在一个特定的桥后面的所有设备上 +3. 在单一设备上 + +全局禁用MSI +----------- + +一些主控芯片组根本无法正确支持MSI。如果我们幸运的话,制造商知道这一点,并在 +ACPI FADT表中指明了它。在这种情况下,Linux会自动禁用MSI。有些板卡在表中没 +有包括这一信息,因此我们必须自己检测它们。完整的列表可以在drivers/pci/quirks.c +中的quirk_disable_all_msi()函数附近找到。 + +如果你有一块有MSI问题的板子,你可以在内核命令行中传递pci=nomsi来禁用所有设 +备上的MSI。你最好把问题报告给linux-pci@vger.kernel.org,包括完整的 +“lspci -v“,这样我们就可以把这些怪癖添加到内核中。 + +禁用桥下的MSI +------------- + +一些PCI桥接器不能在总线之间正确地路由MSI。在这种情况下,必须在桥接器后面的所 +有设备上禁用MSI。 + +一些桥接器允许你通过改变PCI配置空间的一些位来启用MSI(特别是Hypertransport +芯片组,如nVidia nForce和Serverworks HT2000)。与主机芯片组一样,Linux大 +多知道它们,如果可以的话,会自动启用MSI。如果你有一个Linux不知道的网桥,你可以 +用你知道的任何方法在配置空间中启用MSI,然后通过以下方式在该网桥上启用MSI:: + + echo 1 > /sys/bus/pci/devices/$bridge/msi_bus + +其中$bridge是你所启用的桥的PCI地址(例如0000:00:0e.0)。 + +要禁用MSI,请回显0而不是1。改变这个值应该谨慎进行,因为它可能会破坏这个桥下面所 +有设备的中断处理。 + +同样,请通知 linux-pci@vger.kernel.org 任何需要特殊处理的桥。 + +在单一设备上关闭MSIs +-------------------- + +众所周知,有些设备的MSI实现是有问题的。通常情况下,这是在单个设备驱动程序中处理的, +但偶尔也有必要用一个古怪的方法来处理。一些驱动程序有一个选项可以禁用MSI的使用。虽然 +这对驱动程序的作者来说是一个方便的变通办法,但这不是一个好的做法,不应该被模仿。 + +寻找设备上MSI被禁用的原因 +------------------------- + +从以上三个部分,你可以看到有许多原因导致MSI没有在某个设备上被启用。你的第一步应该是 +仔细检查你的dmesg以确定你的机器是否启用了MSI。你还应该检查你的.config以确定你已经 +启用了CONFIG_PCI_MSI。 + +然后,“lspci -t“给出一个设备上面的网列表。读取 ``/sys/bus/pci/devices/*/msi_bus`` +将告诉你MSI是否被启用(1)或禁用(0)。如果在任何属于PCI根和设备之间的桥的msi_bus +文件中发现0,说明MSI被禁用。 + +也需要检查设备驱动程序,看它是否支持MSI。例如,它可能包含对带有PCI_IRQ_MSI或 +PCI_IRQ_MSIX标志的pci_alloc_irq_vectors()的调用。 diff --git a/Documentation/translations/zh_CN/PCI/pci-iov-howto.rst b/Documentation/translations/zh_CN/PCI/pci-iov-howto.rst new file mode 100644 index 000000000000..fbc83dfdcead --- /dev/null +++ b/Documentation/translations/zh_CN/PCI/pci-iov-howto.rst @@ -0,0 +1,170 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: <isonum.txt> +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/PCI/pci-iov-howto.rst + +:翻译: + + 司延腾 Yanteng Si <siyanteng@loongson.cn> + +:校译: + + + +.. _cn_pci-iov-howto: + +========================== +PCI Express I/O 虚拟化指南 +========================== + +:版权: |copy| 2009 Intel Corporation +:作者: - Yu Zhao <yu.zhao@intel.com> + - Donald Dutile <ddutile@redhat.com> + +概述 +==== + +什么是SR-IOV +------------ + +单根I/O虚拟化(SR-IOV)是一种PCI Express扩展功能,它使一个物理设备显示为多个 +虚拟设备。物理设备被称为物理功能(PF),而虚拟设备被称为虚拟功能(VF)。VF的分 +配可以由PF通过封装在该功能中的寄存器动态控制。默认情况下,该功能未被启用,PF表 +现为传统的PCIe设备。一旦开启,每个VF的PCI配置空间都可以通过自己的总线、设备和 +功能编号(路由ID)来访问。而且每个VF也有PCI内存空间,用于映射其寄存器集。VF设 +备驱动程序对寄存器集进行操作,这样它就可以发挥功能,并作为一个真正的现有PCI设备 +出现。 + +使用指南 +======== + +我怎样才能启用SR-IOV功能 +------------------------ + +有多种方法可用于SR-IOV的启用。在第一种方法中,设备驱动(PF驱动)将通过SR-IOV +核心提供的API控制功能的启用和禁用。如果硬件具有SR-IOV能力,加载其PF驱动器将启 +用它和与PF相关的所有VF。一些PF驱动需要设置一个模块参数,以确定要启用的VF的数量。 +在第二种方法中,对sysfs文件sriov_numvfs的写入将启用和禁用与PCIe PF相关的VF。 +这种方法实现了每个PF的VF启用/禁用值,而第一种方法则适用于同一设备的所有PF。此外, +PCI SRIOV核心支持确保启用/禁用操作是有效的,以减少同一检查在多个驱动程序中的重 +复,例如,如果启用VF,检查numvfs == 0,确保numvfs <= totalvfs。 +第二种方法是对新的/未来的VF设备的推荐方法。 + +我怎样才能使用虚拟功能 +---------------------- + +在内核中,VF被视为热插拔的PCI设备,所以它们应该能够以与真正的PCI设备相同的方式 +工作。VF需要的设备驱动与普通PCI设备的驱动相同。 + +开发者指南 +========== + +SR-IOV API +---------- + +用来开启SR-IOV功能: + +(a) 对于第一种方法,在驱动程序中:: + + int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); + +nr_virtfn'是要启用的VF的编号。 + +(b) 对于第二种方法,从sysfs:: + + echo 'nr_virtfn' > \ + /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs + +用来关闭SR-IOV功能: + +(a) 对于第一种方法,在驱动程序中:: + + void pci_disable_sriov(struct pci_dev *dev); + +(b) 对于第二种方法,从sysfs:: + + echo 0 > \ + /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs + +要想通过主机上的兼容驱动启用自动探测VF,在启用SR-IOV功能之前运行下面的命令。这 +是默认的行为。 +:: + + echo 1 > \ + /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe + +要禁止主机上的兼容驱动自动探测VF,请在启用SR-IOV功能之前运行以下命令。更新这个 +入口不会影响已经被探测的VF。 +:: + + echo 0 > \ + /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe + +用例 +---- + +下面的代码演示了SR-IOV API的用法 +:: + + static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id) + { + pci_enable_sriov(dev, NR_VIRTFN); + + ... + + return 0; + } + + static void dev_remove(struct pci_dev *dev) + { + pci_disable_sriov(dev); + + ... + } + + static int dev_suspend(struct pci_dev *dev, pm_message_t state) + { + ... + + return 0; + } + + static int dev_resume(struct pci_dev *dev) + { + ... + + return 0; + } + + static void dev_shutdown(struct pci_dev *dev) + { + ... + } + + static int dev_sriov_configure(struct pci_dev *dev, int numvfs) + { + if (numvfs > 0) { + ... + pci_enable_sriov(dev, numvfs); + ... + return numvfs; + } + if (numvfs == 0) { + .... + pci_disable_sriov(dev); + ... + return 0; + } + } + + static struct pci_driver dev_driver = { + .name = "SR-IOV Physical Function driver", + .id_table = dev_id_table, + .probe = dev_probe, + .remove = dev_remove, + .suspend = dev_suspend, + .resume = dev_resume, + .shutdown = dev_shutdown, + .sriov_configure = dev_sriov_configure, + }; diff --git a/Documentation/translations/zh_CN/PCI/pciebus-howto.rst b/Documentation/translations/zh_CN/PCI/pciebus-howto.rst new file mode 100644 index 000000000000..65c4301f12cd --- /dev/null +++ b/Documentation/translations/zh_CN/PCI/pciebus-howto.rst @@ -0,0 +1,192 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: <isonum.txt> +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/PCI/pciebus-howto.rst + +:翻译: + + 司延腾 Yanteng Si <siyanteng@loongson.cn> + +:校译: + + + +.. _cn_pciebus-howto: + +=========================== +PCI Express端口总线驱动指南 +=========================== + +:作者: Tom L Nguyen tom.l.nguyen@intel.com 11/03/2004 +:版权: |copy| 2004 Intel Corporation + +关于本指南 +========== + +本指南介绍了PCI Express端口总线驱动程序的基本知识,并提供了如何使服务驱 +动程序在PCI Express端口总线驱动程序中注册/取消注册的介绍。 + + +什么是PCI Express端口总线驱动程序 +================================= + +一个PCI Express端口是一个逻辑的PCI-PCI桥结构。有两种类型的PCI Express端 +口:根端口和交换端口。根端口从PCI Express根综合体发起一个PCI Express链接, +交换端口将PCI Express链接连接到内部逻辑PCI总线。交换机端口,其二级总线代表 +交换机的内部路由逻辑,被称为交换机的上行端口。交换机的下行端口是从交换机的内部 +路由总线桥接到代表来自PCI Express交换机的下游PCI Express链接的总线。 + +一个PCI Express端口可以提供多达四个不同的功能,在本文中被称为服务,这取决于 +其端口类型。PCI Express端口的服务包括本地热拔插支持(HP)、电源管理事件支持(PME)、 +高级错误报告支持(AER)和虚拟通道支持(VC)。这些服务可以由一个复杂的驱动程序 +处理,也可以单独分布并由相应的服务驱动程序处理。 + +为什么要使用PCI Express端口总线驱动程序? +========================================= + +在现有的Linux内核中,Linux设备驱动模型允许一个物理设备只由一个驱动处理。 +PCI Express端口是一个具有多个不同服务的PCI-PCI桥设备。为了保持一个干净和简 +单的解决方案,每个服务都可以有自己的软件服务驱动。在这种情况下,几个服务驱动将 +竞争一个PCI-PCI桥设备。例如,如果PCI Express根端口的本机热拔插服务驱动程序 +首先被加载,它就会要求一个PCI-PCI桥根端口。因此,内核不会为该根端口加载其他服 +务驱动。换句话说,使用当前的驱动模型,不可能让多个服务驱动同时加载并运行在 +PCI-PCI桥设备上。 + +为了使多个服务驱动程序同时运行,需要有一个PCI Express端口总线驱动程序,它管 +理所有填充的PCI Express端口,并根据需要将所有提供的服务请求分配给相应的服务 +驱动程序。下面列出了使用PCI Express端口总线驱动程序的一些关键优势: + + - 允许在一个PCI-PCI桥接端口设备上同时运行多个服务驱动。 + + - 允许以独立的分阶段方式实施服务驱动程序。 + + - 允许一个服务驱动程序在多个PCI-PCI桥接端口设备上运行。 + + - 管理和分配PCI-PCI桥接端口设备的资源给要求的服务驱动程序。 + +配置PCI Express端口总线驱动程序与服务驱动程序 +============================================= + +将PCI Express端口总线驱动支持纳入内核 +------------------------------------- + +包括PCI Express端口总线驱动程序取决于内核配置中是否包含PCI Express支持。当内核 +中的PCI Express支持被启用时,内核将自动包含PCI Express端口总线驱动程序作为内核 +驱动程序。 + +启用服务驱动支持 +---------------- + +PCI设备驱动是基于Linux设备驱动模型实现的。所有的服务驱动都是PCI设备驱动。如上所述, +一旦内核加载了PCI Express端口总线驱动程序,就不可能再加载任何服务驱动程序。为了满 +足PCI Express端口总线驱动程序模型,需要对现有的服务驱动程序进行一些最小的改变,其 +对现有的服务驱动程序的功能没有影响。 + +服务驱动程序需要使用下面所示的两个API,将其服务注册到PCI Express端口总线驱动程 +序中(见第5.2.1和5.2.2节)。在调用这些API之前,服务驱动程序必须初始化头文件 +/include/linux/pcieport_if.h中的pcie_port_service_driver数据结构。如果不这 +样做,将导致身份不匹配,从而使PCI Express端口总线驱动程序无法加载服务驱动程序。 + +pcie_port_service_register +~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: + + int pcie_port_service_register(struct pcie_port_service_driver *new) + +这个API取代了Linux驱动模型的 pci_register_driver API。一个服务驱动应该总是在模 +块启动时调用 pcie_port_service_register。请注意,在服务驱动被加载后,诸如 +pci_enable_device(dev) 和 pci_set_master(dev) 的调用不再需要,因为这些调用由 +PCI端口总线驱动执行。 + +pcie_port_service_unregister +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: + + void pcie_port_service_unregister(struct pcie_port_service_driver *new) + +pcie_port_service_unregister取代了Linux驱动模型的pci_unregister_driver。当一 +个模块退出时,它总是被服务驱动调用。 + +示例代码 +~~~~~~~~ + +下面是服务驱动代码示例,用于初始化端口服务的驱动程序数据结构。 +:: + + static struct pcie_port_service_id service_id[] = { { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .port_type = PCIE_RC_PORT, + .service_type = PCIE_PORT_SERVICE_AER, + }, { /* end: all zeroes */ } + }; + + static struct pcie_port_service_driver root_aerdrv = { + .name = (char *)device_name, + .id_table = &service_id[0], + + .probe = aerdrv_load, + .remove = aerdrv_unload, + + .suspend = aerdrv_suspend, + .resume = aerdrv_resume, + }; + +下面是一个注册/取消注册服务驱动的示例代码。 +:: + + static int __init aerdrv_service_init(void) + { + int retval = 0; + + retval = pcie_port_service_register(&root_aerdrv); + if (!retval) { + /* + * FIX ME + */ + } + return retval; + } + + static void __exit aerdrv_service_exit(void) + { + pcie_port_service_unregister(&root_aerdrv); + } + + module_init(aerdrv_service_init); + module_exit(aerdrv_service_exit); + +可能的资源冲突 +============== + +由于PCI-PCI桥接端口设备的所有服务驱动被允许同时运行,下面列出了一些可能的资源冲突和 +建议的解决方案。 + +MSI 和 MSI-X 向量资源 +--------------------- + +一旦设备上的MSI或MSI-X中断被启用,它就会一直保持这种模式,直到它们再次被禁用。由于同 +一个PCI-PCI桥接端口的服务驱动程序共享同一个物理设备,如果一个单独的服务驱动程序启用或 +禁用MSI/MSI-X模式,可能会导致不可预知的行为。 + +为了避免这种情况,所有的服务驱动程序都不允许在其设备上切换中断模式。PCI Express端口 +总线驱动程序负责确定中断模式,这对服务驱动程序来说应该是透明的。服务驱动程序只需要知道 +分配给结构体pcie_device的字段irq的向量IRQ,当PCI Express端口总线驱动程序探测每 +个服务驱动程序时,它被传入。服务驱动应该使用(struct pcie_device*)dev->irq来调用 +request_irq/free_irq。此外,中断模式被存储在struct pcie_device的interrupt_mode +字段中。 + +PCI内存/IO映射的区域 +-------------------- + +PCI Express电源管理(PME)、高级错误报告(AER)、热插拔(HP)和虚拟通道(VC)的服务 +驱动程序访问PCI Express端口的PCI配置空间。在所有情况下,访问的寄存器是相互独立的。这 +个补丁假定所有的服务驱动程序都会表现良好,不会覆盖其他服务驱动程序的配置设置。 + +PCI配置寄存器 +------------- + +每个服务驱动都在自己的功能结构体上运行PCI配置操作,除了PCI Express功能结构体,其中根控制 +寄存器和设备控制寄存器是在PME和AER之间共享。这个补丁假定所有的服务驱动都会表现良好,不会 +覆盖其他服务驱动的配置设置。 diff --git a/Documentation/translations/zh_CN/PCI/sysfs-pci.rst b/Documentation/translations/zh_CN/PCI/sysfs-pci.rst new file mode 100644 index 000000000000..0d75c2e99d52 --- /dev/null +++ b/Documentation/translations/zh_CN/PCI/sysfs-pci.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/PCI/sysfs-pci.rst + +:翻译: + + 司延腾 Yanteng Si <siyanteng@loongson.cn> + +:校译: + + + +======================== +通过sysfs访问PCI设备资源 +======================== + +sysfs,通常挂载在/sys,在支持它的平台上提供对PCI资源的访问。例如,一个特定的总线可能看起 +来像这样:: + + /sys/devices/pci0000:17 + |-- 0000:17:00.0 + | |-- class + | |-- config + | |-- device + | |-- enable + | |-- irq + | |-- local_cpus + | |-- remove + | |-- resource + | |-- resource0 + | |-- resource1 + | |-- resource2 + | |-- revision + | |-- rom + | |-- subsystem_device + | |-- subsystem_vendor + | `-- vendor + `-- ... + +最上面的元素描述了PCI域和总线号码。在这种情况下,域号是0000,总线号是17(两个值都是十六进制)。 +这个总线在0号插槽中包含一个单一功能的设备。为了方便起见,我们复制了域和总线的编号。在设备目录 +下有几个文件,每个文件都有自己的功能。 + + =================== ===================================================== + 文件 功能 + =================== ===================================================== + class PCI级别 (ascii, ro) + config PCI配置空间 (binary, rw) + device PCI设备 (ascii, ro) + enable 设备是否被启用 (ascii, rw) + irq IRQ编号 (ascii, ro) + local_cpus 临近CPU掩码(cpumask, ro) + remove 从内核的列表中删除设备 (ascii, wo) + resource PCI资源主机地址 (ascii, ro) + resource0..N PCI资源N,如果存在的话 (binary, mmap, rw\ [1]_) + resource0_wc..N_wc PCI WC映射资源N,如果可预取的话 (binary, mmap) + revision PCI修订版 (ascii, ro) + rom PCI ROM资源,如果存在的话 (binary, ro) + subsystem_device PCI子系统设备 (ascii, ro) + subsystem_vendor PCI子系统供应商 (ascii, ro) + vendor PCI供应商 (ascii, ro) + =================== ===================================================== + +:: + + ro - 只读文件 + rw - 文件是可读和可写的 + wo - 只写文件 + mmap - 文件是可移动的 + ascii - 文件包含ascii文本 + binary - 文件包含二进制数据 + cpumask - 文件包含一个cpumask类型的 + +.. [1] rw 仅适用于 IORESOURCE_IO(I/O 端口)区域 + +只读文件是信息性的,对它们的写入将被忽略,但 "rom "文件除外。可写文件可以用来在设备上执 +行操作(例如,改变配置空间,分离设备)。 mmapable文件可以通过偏移量为0的文件的mmap获得, +可以用来从用户空间进行实际的设备编程。注意,有些平台不支持某些资源的mmapping,所以一定要 +检查任何尝试的mmap的返回值。其中最值得注意的是I/O端口资源,它也提供读/写访问。 + +enable "文件提供了一个计数器,表明设备已经被启用了多少次。如果'enable'文件目前返回'4', +而一个'1'被呼入它,它将返回'5'。向它呼入一个'0'会减少计数。不过,即使它返回到0,一些初始 +化可能也不会被逆转。 + +rom "文件很特别,因为它提供了对设备ROM文件的只读访问,如果有的话。然而,它在默认情况下是 +禁用的,所以应用程序应该在尝试读取调用之前将字符串 "1 "写入该文件以启用它,并在访问之后将 +"0 "写入该文件以禁用它。请注意,设备必须被启用,才能成功返回数据。如果驱动没有被绑定到设备 +上,可以使用上面提到的 "enable "文件将其启用。 + +remove "文件是用来移除PCI设备的,通过向该文件写入一个非零的整数。这并不涉及任何形式的热插 +拔功能,例如关闭设备的电源。该设备被从内核的PCI设备列表中移除,它的sysfs目录被移除,并且该 +设备将被从任何连接到它的驱动程序中移除。移除PCI根总线是不允许的。 + +通过sysfs访问原有资源 +--------------------- + +如果底层平台支持的话,传统的I/O端口和ISA内存资源也会在sysfs中提供。它们位于PCI类的层次结构 +中,例如:: + + /sys/class/pci_bus/0000:17/ + |-- bridge -> ../../../devices/pci0000:17 + |-- cpuaffinity + |-- legacy_io + `-- legacy_mem + +legacy_io文件是一个读/写文件,可以被应用程序用来做传统的端口I/O。应用程序应该打开该文件,寻 +找所需的端口(例如0x3e8),并进行1、2或4字节的读或写。legacy_mem文件应该被mmapped,其偏移 +量与所需的内存偏移量相对应,例如0xa0000用于VGA帧缓冲器。然后,应用程序可以简单地解除引用返回 +的指针(当然是在检查了错误之后)来访问遗留内存空间。 + +支持新平台上的PCI访问 +--------------------- + +为了支持上述的PCI资源映射,Linux平台代码最好定义ARCH_GENERIC_PCI_MMAP_RESOURCE并使用该 +功能的通用实现。为了支持通过/proc/bus/pci中的文件实现mmap()的历史接口,平台也可以设置 +HAVE_PCI_MMAP。 + +另外,设置了 HAVE_PCI_MMAP 的平台可以提供他们自己的 pci_mmap_page_range() 实现,而不是定 +义 ARCH_GENERIC_PCI_MMAP_RESOURCE。 + +支持PCI资源的写组合映射的平台必须定义arch_can_pci_mmap_wc(),当写组合被允许时,在运行时应 +评估为非零。支持I/O资源映射的平台同样定义arch_can_pci_mmap_io()。 + +遗留资源由HAVE_PCI_LEGACY定义保护。希望支持遗留功能的平台应该定义它并提供 pci_legacy_read, +pci_legacy_write 和 pci_mmap_legacy_page_range 函数。 |