]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pci] Require discovery of a PCI device when determining usable PCI APIs
authorMichael Brown <mcb30@ipxe.org>
Thu, 2 Nov 2023 16:11:38 +0000 (16:11 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 2 Nov 2023 16:11:38 +0000 (16:11 +0000)
The PCI cloud API (PCIAPI_CLOUD) currently selects the first PCI API
that successfully discovers a PCI device address range.  The ECAM API
may discover an address range but subsequently be unable to map the
configuration space region, which would result in the selected PCI API
being unusable.

Fix by instead selecting the first PCI API that can be successfully
used to discover a PCI device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/interface/pcbios/pcicloud.c

index 97d7cac1d688e62c92e00f578c668824ee578fec..98ba38b3193bf1ddb559c97b0f2e80a19c5faf05 100644 (file)
@@ -165,24 +165,27 @@ static void pcicloud_init ( void ) {
        static struct pci_api *apis[] = {
                &ecam_api, &pcibios_api, &pcidirect_api
        };
-       struct pci_range range;
+       struct pci_device pci;
+       uint32_t busdevfn;
        unsigned int i;
+       int rc;
 
-       /* Select first API that successfully discovers an address range */
+       /* Select first API that successfully discovers a PCI device */
        for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) {
                pcicloud = apis[i];
-               pcicloud_discover ( 0, &range );
-               if ( range.count != 0 ) {
-                       DBGC ( pcicloud, "PCICLOUD selected %s API\n",
-                              pcicloud->name );
-                       break;
+               busdevfn = 0;
+               if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) == 0 ) {
+                       DBGC ( pcicloud, "PCICLOUD selected %s API (found "
+                              PCI_FMT ")\n", pcicloud->name,
+                              PCI_ARGS ( &pci ) );
+                       return;
                }
        }
 
-       /* The PCI direct API can never fail discovery since the range
-        * is hardcoded.
-        */
-       assert ( range.count != 0 );
+       /* Fall back to using final attempted API if no devices found */
+       pcicloud = apis[ i - 1 ];
+       DBGC ( pcicloud, "PCICLOUD selected %s API (nothing detected)\n",
+              pcicloud->name );
 }
 
 /** Cloud VM PCI configuration space access initialisation function */