diff --git a/src/arch/x86/core/pcidirect.c b/src/arch/x86/core/pcidirect.c index f4659a1ac..90d4623b3 100644 --- a/src/arch/x86/core/pcidirect.c +++ b/src/arch/x86/core/pcidirect.c @@ -45,6 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) { PCIDIRECT_CONFIG_ADDRESS ); } +PROVIDE_PCIAPI_INLINE ( direct, pci_can_probe ); PROVIDE_PCIAPI_INLINE ( direct, pci_discover ); PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word ); diff --git a/src/arch/x86/include/ipxe/pcibios.h b/src/arch/x86/include/ipxe/pcibios.h index 3caea1cfe..ef9585654 100644 --- a/src/arch/x86/include/ipxe/pcibios.h +++ b/src/arch/x86/include/ipxe/pcibios.h @@ -32,6 +32,16 @@ extern int pcibios_read ( struct pci_device *pci, uint32_t command, extern int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ); +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( pcbios, pci_can_probe ) ( void ) { + return 1; +} + /** * Read byte from PCI configuration space via PCI BIOS * diff --git a/src/arch/x86/include/ipxe/pcicloud.h b/src/arch/x86/include/ipxe/pcicloud.h index 52268908c..1feef56cb 100644 --- a/src/arch/x86/include/ipxe/pcicloud.h +++ b/src/arch/x86/include/ipxe/pcicloud.h @@ -15,4 +15,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define PCIAPI_PREFIX_cloud __cloud_ #endif +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( cloud, pci_can_probe ) ( void ) { + return 1; +} + #endif /* _IPXE_PCICLOUD_H */ diff --git a/src/arch/x86/include/ipxe/pcidirect.h b/src/arch/x86/include/ipxe/pcidirect.h index 98c6a2bbb..999b52763 100644 --- a/src/arch/x86/include/ipxe/pcidirect.h +++ b/src/arch/x86/include/ipxe/pcidirect.h @@ -25,6 +25,16 @@ struct pci_device; extern void pcidirect_prepare ( struct pci_device *pci, int where ); +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( direct, pci_can_probe ) ( void ) { + return 1; +} + /** * Find next PCI bus:dev.fn address range in system * diff --git a/src/arch/x86/interface/pcbios/pcibios.c b/src/arch/x86/interface/pcbios/pcibios.c index 7b7a769e3..ebe40ba7d 100644 --- a/src/arch/x86/interface/pcbios/pcibios.c +++ b/src/arch/x86/interface/pcbios/pcibios.c @@ -120,6 +120,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){ return ( status >> 8 ); } +PROVIDE_PCIAPI_INLINE ( pcbios, pci_can_probe ); PROVIDE_PCIAPI ( pcbios, pci_discover, pcibios_discover ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word ); diff --git a/src/arch/x86/interface/pcbios/pcicloud.c b/src/arch/x86/interface/pcbios/pcicloud.c index 98ba38b31..f7d4a2da1 100644 --- a/src/arch/x86/interface/pcbios/pcicloud.c +++ b/src/arch/x86/interface/pcbios/pcicloud.c @@ -148,6 +148,7 @@ static void * pcicloud_ioremap ( struct pci_device *pci, return pcicloud->pci_ioremap ( pci, bus_addr, len ); } +PROVIDE_PCIAPI_INLINE ( cloud, pci_can_probe ); PROVIDE_PCIAPI ( cloud, pci_discover, pcicloud_discover ); PROVIDE_PCIAPI ( cloud, pci_read_config_byte, pcicloud_read_config_byte ); PROVIDE_PCIAPI ( cloud, pci_read_config_word, pcicloud_read_config_word ); diff --git a/src/drivers/bus/ecam.c b/src/drivers/bus/ecam.c index 5e3debddd..cde5952b8 100644 --- a/src/drivers/bus/ecam.c +++ b/src/drivers/bus/ecam.c @@ -276,6 +276,7 @@ int ecam_write ( struct pci_device *pci, unsigned int location, return 0; } +PROVIDE_PCIAPI_INLINE ( ecam, pci_can_probe ); PROVIDE_PCIAPI ( ecam, pci_discover, ecam_discover ); PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_word ); diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c index 92b389641..05c9a5c26 100644 --- a/src/drivers/bus/pci.c +++ b/src/drivers/bus/pci.c @@ -361,6 +361,10 @@ static int pcibus_probe ( struct root_device *rootdev ) { uint32_t busdevfn = 0; int rc; + /* Skip automatic probing if prohibited */ + if ( ! pci_can_probe() ) + return 0; + do { /* Allocate struct pci_device */ if ( ! pci ) diff --git a/src/include/ipxe/ecam.h b/src/include/ipxe/ecam.h index ff08aee5a..f656083f7 100644 --- a/src/include/ipxe/ecam.h +++ b/src/include/ipxe/ecam.h @@ -54,6 +54,16 @@ struct ecam_mapping { int rc; }; +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( ecam, pci_can_probe ) ( void ) { + return 1; +} + extern struct pci_api ecam_api; #endif /* _IPXE_ECAM_H */ diff --git a/src/include/ipxe/efi/efi_pci_api.h b/src/include/ipxe/efi/efi_pci_api.h index cf5e1d020..0c4c1b72c 100644 --- a/src/include/ipxe/efi/efi_pci_api.h +++ b/src/include/ipxe/efi/efi_pci_api.h @@ -32,6 +32,16 @@ extern int efipci_read ( struct pci_device *pci, unsigned long location, extern int efipci_write ( struct pci_device *pci, unsigned long location, unsigned long value ); +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( efi, pci_can_probe ) ( void ) { + return 0; +} + /** * Find next PCI bus:dev.fn address range in system * diff --git a/src/include/ipxe/linux/linux_pci.h b/src/include/ipxe/linux/linux_pci.h index ec6ff8b1c..2b19e13c3 100644 --- a/src/include/ipxe/linux/linux_pci.h +++ b/src/include/ipxe/linux/linux_pci.h @@ -22,6 +22,16 @@ extern int linux_pci_read ( struct pci_device *pci, unsigned long where, extern int linux_pci_write ( struct pci_device *pci, unsigned long where, unsigned long value, size_t len ); +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +static inline __always_inline int +PCIAPI_INLINE ( linux, pci_can_probe ) ( void ) { + return 1; +} + /** * Find next PCI bus:dev.fn address range in system * diff --git a/src/include/ipxe/pci_io.h b/src/include/ipxe/pci_io.h index 4c035b18b..322fdbb24 100644 --- a/src/include/ipxe/pci_io.h +++ b/src/include/ipxe/pci_io.h @@ -66,6 +66,13 @@ struct pci_range { /* Include all architecture-dependent I/O API headers */ #include +/** + * Check if PCI bus probing is allowed + * + * @ret ok Bus probing is allowed + */ +int pci_can_probe ( void ); + /** * Find next PCI bus:dev.fn address range in system * diff --git a/src/interface/efi/efi_pci.c b/src/interface/efi/efi_pci.c index e2eeeb344..61071d8a4 100644 --- a/src/interface/efi/efi_pci.c +++ b/src/interface/efi/efi_pci.c @@ -362,6 +362,7 @@ void * efipci_ioremap ( struct pci_device *pci, unsigned long bus_addr, return ioremap ( bus_addr, len ); } +PROVIDE_PCIAPI_INLINE ( efi, pci_can_probe ); PROVIDE_PCIAPI_INLINE ( efi, pci_discover ); PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_word ); diff --git a/src/interface/linux/linux_pci.c b/src/interface/linux/linux_pci.c index 300844737..a3a0828c1 100644 --- a/src/interface/linux/linux_pci.c +++ b/src/interface/linux/linux_pci.c @@ -188,6 +188,7 @@ int linux_pci_write ( struct pci_device *pci, unsigned long where, return rc; } +PROVIDE_PCIAPI_INLINE ( linux, pci_can_probe ); PROVIDE_PCIAPI_INLINE ( linux, pci_discover ); PROVIDE_PCIAPI_INLINE ( linux, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( linux, pci_read_config_word );