[ipxe-devel] [PATCH 1/1] efi: reimplement efi_locate_device
Heinrich Schuchardt
xypron.glpk at gmx.de
Wed Jul 12 17:46:51 UTC 2017
Currently efi_locate_device looks for a device supporting a
protocol only in the list of parents. This leads to errors like
EFIDEV mmc at 72000.blk has no parent supporting SimpleNetwork
Obviously looking for a network protocol in a block device or
its parents does not make sense.
With the patch efi_locate_device returns the device if it supports
the protocol. Otherwise it returns the fist device it can find
supporting the protocol.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
src/interface/efi/efi_utils.c | 57 ++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 28 deletions(-)
diff --git a/src/interface/efi/efi_utils.c b/src/interface/efi/efi_utils.c
index 4dc75414..5069ce9d 100644
--- a/src/interface/efi/efi_utils.c
+++ b/src/interface/efi/efi_utils.c
@@ -63,7 +63,7 @@ size_t efi_devpath_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
}
/**
- * Locate parent device supporting a given protocol
+ * Locate device supporting a given protocol
*
* @v device EFI device handle
* @v protocol Protocol GUID
@@ -73,44 +73,45 @@ size_t efi_devpath_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
EFI_HANDLE *parent ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_DEVICE_PATH_PROTOCOL *path;
- void *interface;
- } path;
- EFI_DEVICE_PATH_PROTOCOL *devpath;
EFI_STATUS efirc;
+ EFI_HANDLE *handles;
+ UINTN num_handles;
+ UINTN i;
int rc;
- /* Get device path */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_device_path_protocol_guid,
- &path.interface,
- efi_image_handle, device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+ /* Identify candidate handles */
+ if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
+ NULL, &num_handles,
+ &handles ) ) != 0 ) {
rc = -EEFI ( efirc );
- DBGC ( device, "EFIDEV %s cannot open device path: %s\n",
- efi_handle_name ( device ), strerror ( rc ) );
- goto err_open_device_path;
+ DBGC ( device, "EFIDEV found no handle supporting %s: %s\n",
+ efi_guid_ntoa ( protocol ), strerror ( rc ) );
+ return rc;
}
- devpath = path.path;
- /* Check for presence of specified protocol */
- if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
- parent ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIDEV %s has no parent supporting %s: %s\n",
- efi_handle_name ( device ),
- efi_guid_ntoa ( protocol ), strerror ( rc ) );
- goto err_locate_protocol;
+ if (!num_handles || !*handles)
+ return -EEFI( EFI_NOT_FOUND);
+
+ *parent = NULL;
+
+ /* If device provice supports the protocol then return it. */
+ for ( i = 0; i < num_handles; ++i ) {
+ if (device == handles[i]) {
+ *parent = device;
+ break;
+ }
}
+ /* Otherwise use first handle supporting the protocol. */
+ if ( !*parent && num_handles )
+ *parent = handles[0];
+
+ /* Clean up */
+ bs->FreePool( handles );
+
/* Success */
rc = 0;
- err_locate_protocol:
- bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
- efi_image_handle, device );
- err_open_device_path:
return rc;
}
--
2.11.0
More information about the ipxe-devel
mailing list