[U-Boot] [PATCH v2 05/18] efi_loader: reimplement LocateDevicePath
Heinrich Schuchardt
xypron.glpk at gmx.de
Fri Nov 17 18:20:46 UTC 2017
On 11/17/2017 03:06 PM, Simon Glass wrote:
> Hi Heinrich,
>
> On 12 November 2017 at 07:02, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
>> The current implementation of efi_locate_device_path does not match
>> the UEFI specification. It completely ignores the protocol
>> parameters.
>>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
>> ---
>> v2
>> no change
>> ---
>> lib/efi_loader/efi_boottime.c | 106 ++++++++++++++++++++++++++++++------------
>> 1 file changed, 76 insertions(+), 30 deletions(-)
>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> Nits below
>
>>
>> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
>> index 9b5512f086..7457d54739 100644
>> --- a/lib/efi_loader/efi_boottime.c
>> +++ b/lib/efi_loader/efi_boottime.c
>> @@ -1080,36 +1080,6 @@ static efi_status_t EFIAPI efi_locate_handle_ext(
>> buffer_size, buffer));
>> }
>>
>> -/*
>> - * Get the device path and handle of an device implementing a protocol.
>> - *
>> - * This function implements the LocateDevicePath service.
>> - * See the Unified Extensible Firmware Interface (UEFI) specification
>> - * for details.
>
> Oh yes, I will get right on that now :-)
>
>> - *
>> - * @protocol GUID of the protocol
>> - * @device_path device path
>> - * @device handle of the device
>> - * @return status code
>> - */
>> -static efi_status_t EFIAPI efi_locate_device_path(
>> - const efi_guid_t *protocol,
>> - struct efi_device_path **device_path,
>> - efi_handle_t *device)
>> -{
>> - struct efi_object *efiobj;
>> -
>> - EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device);
>> -
>> - efiobj = efi_dp_find_obj(*device_path, device_path);
>> - if (!efiobj)
>> - return EFI_EXIT(EFI_NOT_FOUND);
>> -
>> - *device = efiobj->handle;
>> -
>> - return EFI_EXIT(EFI_SUCCESS);
>> -}
>> -
>> /* Collapses configuration table entries, removing index i */
>> static void efi_remove_configuration_table(int i)
>> {
>> @@ -1813,6 +1783,82 @@ static efi_status_t EFIAPI efi_locate_protocol(const efi_guid_t *protocol,
>> return EFI_EXIT(EFI_NOT_FOUND);
>> }
>>
>> +/*
>> + * Get the device path and handle of an device implementing a protocol.
>
> a device?
>
>> + *
>> + * This function implements the LocateDevicePath service.
>> + * See the Unified Extensible Firmware Interface (UEFI) specification
>> + * for details.
>> + *
>> + * @protocol GUID of the protocol
>> + * @device_path device path
>> + * @device handle of the device
>> + * @return status code
>> + */
>> +static efi_status_t EFIAPI efi_locate_device_path(
>> + const efi_guid_t *protocol,
>> + struct efi_device_path **device_path,
>> + efi_handle_t *device)
>> +{
>> + struct efi_device_path *dp;
>> + size_t i;
>> + struct efi_handler *handler;
>> + efi_handle_t *handles;
>> + size_t len, len_dp;
>> + size_t len_best = 0;
>> + efi_uintn_t no_handles;
>
> Is there none?
>
> I think num_handles is better, or handles_count.
In the UEFI spec this is the name of the parameter of LocateHandleBuffer
and it is also the parameter name in efi_locate_handle_buffer.
I get confused when using different names for the same thing.
>
>> + u8 *remainder;
>> + efi_status_t ret;
>> +
>> + EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device);
>> +
>> + if (!protocol || !device_path || !*device_path || !device) {
>> + ret = EFI_INVALID_PARAMETER;
>> + goto out;
>> + }
>> +
>> + /* Find end of device path */
>> + len = efi_dp_size(*device_path);
>> +
>> + /* Get all handles implementing the protocol */
>> + ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL, protocol, NULL,
>> + &no_handles, &handles));
>> + if (ret != EFI_SUCCESS)
>> + goto out;
>> +
>> + for (i = 0; i < no_handles; ++i) {
>> + /* Find the device path protocol */
>> + ret = efi_search_protocol(handles[i], &efi_guid_device_path,
>> + &handler);
>> + if (ret != EFI_SUCCESS)
>> + continue;
>> + dp = (struct efi_device_path *)handler->protocol_interface;
>> + len_dp = efi_dp_size(dp);
>> + /*
>> + * This handle can only be a better fit
>> + * if its device path length is longer then the best fit and
>> + * if its device path length is shorter of equal the searched
>> + * device path.
>
> Format to ~77 cols?
I deliberately put the two conditions in separate lines to make the text
easier to read. I could have added bullet points but that looked like
overkill to me.
>
>> + */
>> + if (len_dp <= len_best || len_dp > len)
>> + continue;
>> + /* Check if dp is a subpath of device_path. */
>
> Can you drop the period?
Sure.
Regards
Heinrich
>
>> + if (memcmp(*device_path, dp, len_dp))
>> + continue;
>> + *device = handles[i];
>> + len_best = len_dp;
>> + }
>> + if (len_best) {
>> + remainder = (u8 *)*device_path + len_best;
>> + *device_path = (struct efi_device_path *)remainder;
>> + ret = EFI_SUCCESS;
>> + } else {
>> + ret = EFI_NOT_FOUND;
>> + }
>> +out:
>> + return EFI_EXIT(ret);
>> +}
>> +
>> /*
>> * Install multiple protocol interfaces.
>> *
>> --
>> 2.15.0
>>
> Regards,
> Simon
>
More information about the U-Boot
mailing list