pciutil: Enumerate alternative PCIe bus
Subsystems (2)
PATCH 1/1 pciutil: Enumerate alternative PCIe bus
Start enumerating at a specific bus number, this allows accessing root complexes that do not start a busnumber 0. (e.g. Intel Corporation Xeon E5/Core internal components and root complex on second CPU).
--- lib/generic.c | 3 ++- lib/i386-ports.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-)
lib/generic.c +2 -1
@@ -69,9 +69,10 @@ void pci_generic_scan(struct pci_access *a) {byte busmap[256 ]; +int basebus =strtol (pci_get_param (a,"i386.basebus" ),NULL ,16 );memset (busmap,0 ,sizeof (busmap)); -pci_generic_scan_bus (a, busmap,0 ); +pci_generic_scan_bus (a, busmap, basebus); }int
lib/i386-ports.c +9 -2
@@ -32,6 +32,13 @@static int conf12_io_enabled =-1 ;/* -1=haven't tried, 0=failed, 1=succeeded */ +static void +conf12_config (struct pci_access *a) +{ +pci_define_param (a,"i386.basebus" ,"0" ,"Start busnumber for scanning" ); +} + +static int conf12_setup_io (struct pci_access *a) {
@@ -261,7 +268,7 @@ conf2_write(struct pci_dev *d, int pos, byte *buf, int len)struct pci_methods pm_intel_conf1 = {"intel-conf1" ,"Raw I/O port access using Intel conf1 interface" , -NULL ,/* config */ + conf12_config,/* config */ conf1_detect, conf12_init, conf12_cleanup,
@@ -277,7 +284,7 @@ struct pci_methods pm_intel_conf1 = {struct pci_methods pm_intel_conf2 = {"intel-conf2" ,"Raw I/O port access using Intel conf2 interface" , -NULL ,/* config */ + conf12_config,/* config */ conf2_detect, conf12_init, conf12_cleanup,
Signature · 1 line
1.7.0.4
Hello!
lib/generic.c void · line 72
Quoted 9 lines
lib/generic.c +1
-0@@ -69,9 +69,10 @@ void pci_generic_scan(struct pci_access *a) {byte busmap[256 ]; +int basebus =strtol (pci_get_param (a,"i386.basebus" ),NULL ,16 );
Sorry, but this is utterly wrong. This function is not specific to i386 at all.
I will add a different work-around soon.
(Also, please note that using the i386 access methods on Linux is inherently unsafe as there is no locking between accesses by different processes and by the kernel. There are available only as a last resort when everything else fails.)
Martin
Hi Martin,
Quoted 2 lines
Sorry, but this is utterly wrong. This function is not specific to i386 at all.
No need to say sorry, you are the expert :)
Quoted 2 lines
I will add a different work-around soon.
Thanks, looking forward to it.
Quoted 4 lines
(Also, please note that using the i386 access methods on Linux is inherently unsafe as there is no locking between accesses by different processes and by the kernel. There are available only as a last resort when everything else fails.)
I know, if you look at my other posts you will see I got some problems in hooking up an external chassis to a server. But I will not bother you with that too much. Problem is that the linux kernel will try to follow the PCIe busnumbering that the BIOS has installed. That leads to problems when the chassis contains about 12 switches that need to fit in the range the bios has set (which of course is too small and also assigns 64bit bars below 4G).
Turning knobs on the PCIe busnumbering seems to confuse the linux kernel quite a bit when it has knowledge of that switch. However when I remove (1 > remove) the switches at the root complex level, they also disappear from the sysfs. This makes it difficult to manipulate (clear) settings using the linux kernel. setpci allows to bypass the kernel, but clearly no locking is implemented on the io ports thus if the kernel decides to access the PCI configuration io ports at the same time as setpci its heading for disaster.
I will keep my fingers crossed for now, I expect the kernel not to do too much PCI config via io once the system is booted.
It would be nice to orchestrate better with the kernel however afaik there is no lowlevel interface at the sysfs level that allows to address devices that are not enumerated (e.g. by directly accessing the MMIO_BASE?) and keeps the kernel "informed". But perhaps I am wrong.
Best regards,
Ruud