我有一个设备驱动程序,用于通过PCIe GEN2 x16电缆链接控制连接到基于x86的工作站的测试仪系统。测试仪系统由PCIe交换机结构(Avago,以前称为PLX)组成,基于插槽的系统最多可容纳40台仪器,每台仪器都是独立的PCIe设备,由4个PCIe通道驱动(PCIE交换机采用x16链接并将其分解为40个单独的PCIe链接)。这导致多达100个PCI总线成为结构的一部分。这完全符合最大256总线的PCI规范。
我们遇到的问题是某些主板的BIOS坏了,测试仪已经完全填满,BIOS无法正常发送,工作站无法启动(它甚至无法进入BIOS)闪屏)。为了解决这个问题,我们将硬件的PCIe交换机初始配置为“隐藏”#34;大多数PCIe架构使用Avago PCIe交换机具有的虚拟交换机功能(如果有人想要详细信息,请询问)。这允许BIOS启动,因为这次只能看到几条总线。我们的驱动程序在加载时检测到此模式,然后写入PCIe交换机配置寄存器以使整个结构可见。
然后在顶级PCIe交换机上调用pci_stop_and_remove_bus_device,然后使用对父总线设备的引用,告诉它重新扫描总线(pci_rescan_bus)。这里的问题是,这个交换机最初只有几个总线,现在有几十个。如果某些其他总线或设备最初存在的位置高于我们的测试仪结构,则重新扫描显然不够聪明,无法意识到它无法在以前存在的设备之上分配这些新总线。
例如,最初我们的最小化结构位于总线2,其辅助总线分配总线3,底层结构延伸到总线8.然后,可能主板上有另一个根端口,带有板载设备或插入插槽卡那是9路和10路公交车。
现在,当我们"取消隐藏"我们的结构,并使40多个总线可见并重新扫描,它不会重新定位9号和10号总线上现有设备的起点,它开始从2重新分配它们,最多42个,覆盖在设备顶部9和10.这是非法的。我们为Centos 6(Linux内核2.6.32)所做的是重新编写pci_bus结构和配置寄存器,以将父端口的主要,辅助和从属总线移动到现有设备之上的范围,在上面的示例中这将在重新扫描之前从11路公交车开始。这在Centos(RHEL)6下运行得非常好,但在Centos(RHEL 7)内核3.10.0上没有用。似乎用于保存次要和从属号码的pci_bus结构被改变为某种内部资源。即使我更改了资源中的数字,当我调用pci_rescan_bus时内核崩溃(显然,整个事情都冻结了)。它可能与这些资源对象的管理有关,但它们似乎是内部的,而不是外部可修改的。
对于长篇大论的解释感到抱歉,但这一切都是相关的。我的基本问题是如何使用免费的PCI总线编号正确合法地重新枚举扩展的PCIe架构?