pc386: scan all functions of multi-function PCI devices

The current algorithm scans all PCI busses (0..ff)
 and all devices (0..31) on each bus for bridges
 and determines the maximum of all subordinate
 busses encountered.

 However, the algorithm does not scan all functions
 present in multi-function devices -- I have a PCI express
 root complex (82801H) where multiple (non-zero index)
 functions are 'PCI bridges' whose subordinate bus number is
 missed by the original algorithm.

 This commit makes sure that the scan
 is extended to all functions of multi-function
 devices.

 See #2067
This commit is contained in:
Till Strauman
2014-12-23 22:27:25 -05:00
committed by Gedare Bloom
parent 8553d6495f
commit e446d32687

View File

@@ -232,6 +232,8 @@ pci_bus_count()
if ( ucBusCount == 0xff ) { if ( ucBusCount == 0xff ) {
unsigned char bus; unsigned char bus;
unsigned char dev; unsigned char dev;
unsigned char fun;
unsigned char nfn;
unsigned char hd = 0; unsigned char hd = 0;
uint32_t d = 0; uint32_t d = 0;
int sig; int sig;
@@ -243,15 +245,29 @@ pci_bus_count()
sig = PCIB_DEVSIG_MAKE(bus,dev,0); sig = PCIB_DEVSIG_MAKE(bus,dev,0);
pcib_conf_read32(sig, PCI_VENDOR_ID, &d); pcib_conf_read32(sig, PCI_VENDOR_ID, &d);
if ( d != -1 ) { if ( -1 == d ) {
pcib_conf_read32(sig, PCI_CLASS_REVISION, &d); continue;
}
if ( (d >> 16) == PCI_CLASS_BRIDGE_PCI ) { pcib_conf_read8(sig, PCI_HEADER_TYPE, &hd);
pcib_conf_read8(sig, PCI_SUBORDINATE_BUS, &hd); nfn = (hd & 0x80) ? PCI_MAX_FUNCTIONS : 1;
for ( fun=0; fun<nfn; fun++ ) {
sig = PCIB_DEVSIG_MAKE(bus,dev,fun);
pcib_conf_read32(sig, PCI_VENDOR_ID, &d);
if ( -1 == d )
continue;
pcib_conf_read32(sig, PCI_CLASS_REVISION, &d);
if ( (d >> 16) == PCI_CLASS_BRIDGE_PCI ) {
pcib_conf_read8(sig, PCI_SUBORDINATE_BUS, &hd);
if ( hd > ucBusCount )
ucBusCount = hd;
}
if ( hd > ucBusCount )
ucBusCount = hd;
}
} }
} }
} }