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

