Currently efi_locate_device looks for a device supporting a
protocol only in the list of parents. This leads to errors like
EFIDEV [email protected] 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 <[email protected]>
---
 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

_______________________________________________
ipxe-devel mailing list
[email protected]
https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel

Reply via email to