mirror of
https://github.com/xcat2/xNBA.git
synced 2025-02-11 16:23:47 +00:00
[efi] Work around platforms which choke on EFI_PCI_DEVICE_ENABLE
EFI_PCI_DEVICE_ENABLE is a list of the standard attributes that must be enabled for a PCI device to function: I/O cycles, memory cycles, and bus-mastering. We currently call EFI_PCI_IO_PROTOCOL::Attribute() with the parameter EFI_PCI_DEVICE_ENABLE to enable a PCI device. This should translate to a single write to PCI configuration space. Simplicity is not a virtue within the UEFI world. Some platforms will 'helpfully' report an error if EFI_PCI_DEVICE_ENABLE is used on a device that doesn't actually support all three of the relevant attributes. For example, if a PCI device provides only memory-mapped accesses (and so hardwires the I/O enable bit to zero), then using EFI_PCI_DEVICE_ENABLE on such a platform will result in an EFI_UNSUPPORTED error. There is no plausible use case in which it is useful for the platform to return an error in this way, and doing so makes it impossible to distinguish genuine errors from noise. Work around this broken behaviour by attempting to enable the three attributes individually, and ignoring any errors. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
73b21174b2
commit
1af9284225
@ -216,17 +216,19 @@ struct efi_pci_device * efipci_create ( struct efi_driver *efidrv,
|
||||
*/
|
||||
EFI_STATUS efipci_enable ( struct efi_pci_device *efipci ) {
|
||||
EFI_PCI_IO_PROTOCOL *pci_io = efipci->pci_io;
|
||||
EFI_STATUS efirc;
|
||||
|
||||
/* Enable device */
|
||||
if ( ( efirc = pci_io->Attributes ( pci_io,
|
||||
EfiPciIoAttributeOperationSet,
|
||||
EFI_PCI_DEVICE_ENABLE,
|
||||
NULL ) ) != 0 ) {
|
||||
DBGC ( efipci, "EFIPCI " PCI_FMT " could not be enabled: %s\n",
|
||||
PCI_ARGS ( &efipci->pci ), efi_strerror ( efirc ) );
|
||||
return efirc;
|
||||
}
|
||||
/* Try to enable I/O cycles, memory cycles, and bus mastering.
|
||||
* Some platforms will 'helpfully' report errors if these bits
|
||||
* can't be enabled (for example, if the card doesn't actually
|
||||
* support I/O cycles). Work around any such platforms by
|
||||
* enabling bits individually and simply ignoring any errors.
|
||||
*/
|
||||
pci_io->Attributes ( pci_io, EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_IO_ATTRIBUTE_IO, NULL );
|
||||
pci_io->Attributes ( pci_io, EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_IO_ATTRIBUTE_MEMORY, NULL );
|
||||
pci_io->Attributes ( pci_io, EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, NULL );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user