]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Enumerate PCI BARs in same order as SnpDxe
authorMichael Brown <mcb30@ipxe.org>
Fri, 21 Jul 2017 13:48:27 +0000 (14:48 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 21 Jul 2017 14:00:17 +0000 (15:00 +0100)
The UEFI specification has an implicit and demonstrably incorrect
requirement (in the Mem_IO() calling convention) that any UNDI network
device has at most one memory BAR and one I/O BAR.

Some UEFI platforms have been observed to report the existence of
non-existent additional I/O BARs, causing iPXE to select the wrong
BAR.  This problem does not affect the SnpDxe driver, since that
driver will always choose the lowest numbered existent BAR of each
type.

Adjust iPXE's behaviour to match that of SnpDxe, i.e. to always select
the lowest numbered BAR(s).

Debugged-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Debugged-by: Adklei <adklei@realtek.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/efi/nii.c

index d76bfb898971022b2a256f0fdfd6c850c531047a..1c6980e69a35d891c1ba1064cc93a67ac6120b40 100644 (file)
@@ -202,7 +202,7 @@ static int nii_pci_open ( struct nii_nic *nii ) {
                EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
                void *resource;
        } desc;
-       unsigned int bar;
+       int bar;
        EFI_STATUS efirc;
        int rc;
 
@@ -230,7 +230,7 @@ static int nii_pci_open ( struct nii_nic *nii ) {
        /* Identify memory and I/O BARs */
        nii->mem_bar = PCI_MAX_BAR;
        nii->io_bar = PCI_MAX_BAR;
-       for ( bar = 0 ; bar < PCI_MAX_BAR ; bar++ ) {
+       for ( bar = ( PCI_MAX_BAR - 1 ) ; bar >= 0 ; bar-- ) {
                efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
                                                        &desc.resource );
                if ( efirc == EFI_UNSUPPORTED ) {