diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2018-04-16 07:59:09 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2018-04-23 21:34:28 +0200 |
commit | 3acef5da40f694af74f6165ffd47041231d9e6e1 (patch) | |
tree | c900831b64de9c453d3a03383a77bbe8b071dc61 /lib/efi_loader/efi_device_path.c | |
parent | f6dd3f359c346da64f7db331b82086270388da0c (diff) | |
download | u-boot-3acef5da40f694af74f6165ffd47041231d9e6e1.tar.gz |
efi_loader: complete EFI_DEVICE_PATH_UTILITIES_PROTOCOL
The missing services of the EFI_DEVICE_PATH_UTILITIES_PROTOCOL are
implemented.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib/efi_loader/efi_device_path.c')
-rw-r--r-- | lib/efi_loader/efi_device_path.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index ada0a9c268..634dacf41b 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -351,6 +351,70 @@ struct efi_device_path *efi_dp_create_device_node(const u8 type, return ret; } +struct efi_device_path *efi_dp_append_instance( + const struct efi_device_path *dp, + const struct efi_device_path *dpi) +{ + size_t sz, szi; + struct efi_device_path *p, *ret; + + if (!dpi) + return NULL; + if (!dp) + return efi_dp_dup(dpi); + sz = efi_dp_size(dp); + szi = efi_dp_instance_size(dpi); + p = dp_alloc(sz + szi + 2 * sizeof(END)); + if (!p) + return NULL; + ret = p; + memcpy(p, dp, sz + sizeof(END)); + p = (void *)p + sz; + p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END; + p = (void *)p + sizeof(END); + memcpy(p, dpi, szi); + p = (void *)p + szi; + memcpy(p, &END, sizeof(END)); + return ret; +} + +struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp, + efi_uintn_t *size) +{ + size_t sz; + struct efi_device_path *p; + + if (size) + *size = 0; + if (!dp || !*dp) + return NULL; + p = *dp; + sz = efi_dp_instance_size(*dp); + p = dp_alloc(sz + sizeof(END)); + if (!p) + return NULL; + memcpy(p, *dp, sz + sizeof(END)); + *dp = (void *)*dp + sz; + if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END) + *dp = (void *)*dp + sizeof(END); + else + *dp = NULL; + if (size) + *size = sz + sizeof(END); + return p; +} + +bool efi_dp_is_multi_instance(const struct efi_device_path *dp) +{ + const struct efi_device_path *p = dp; + + if (!p) + return false; + while (p->type != DEVICE_PATH_TYPE_END) + p = (void *)p + p->length; + return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END; +} + #ifdef CONFIG_DM /* size of device-path not including END node for device and all parents * up to the root device. |