[U-Boot] [RFC v2 06/15] efi_loader: device path: convert efi_device_path to DM
AKASHI Takahiro
takahiro.akashi at linaro.org
Fri Feb 8 08:15:33 UTC 2019
Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
include/efi_loader.h | 4 +-
lib/efi_loader/efi_device_path.c | 136 ++++++++++++++-------
lib/efi_loader/efi_device_path_to_text.c | 55 +++++++++
lib/efi_loader/efi_device_path_utilities.c | 14 +++
4 files changed, 164 insertions(+), 45 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 4df965455c21..2773df4a26e9 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -386,8 +386,8 @@ extern void *efi_bounce_buffer;
struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
int efi_dp_match(const struct efi_device_path *a,
const struct efi_device_path *b);
-struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
- struct efi_device_path **rem);
+efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
+ struct efi_device_path **rem);
/* get size of the first device path instance excluding end node */
efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
/* size of multi-instance device path excluding end node */
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index d94982314a3e..a85a2d0ff6ba 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -140,69 +140,92 @@ static struct efi_device_path *shorten_path(struct efi_device_path *dp)
return dp;
}
-static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
- struct efi_device_path **rem)
+struct dp_param {
+ struct efi_device_path *dp;
+ bool short_path;
+ struct efi_device_path **rem;
+ struct udevice *dev;
+};
+
+static int find_obj_cb(struct udevice *dev, void *arg)
{
- struct efi_object *efiobj;
+ struct dp_param *param = arg;
+ struct efi_device_path *dp = param->dp;
+ bool short_path = param->short_path;
+ struct efi_device_path **rem = param->rem;
efi_uintn_t dp_size = efi_dp_instance_size(dp);
- list_for_each_entry(efiobj, &efi_obj_list, link) {
- struct efi_handler *handler;
- struct efi_device_path *obj_dp;
- efi_status_t ret;
-
- ret = efi_search_protocol(efiobj,
- &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
- continue;
- obj_dp = handler->protocol_interface;
-
- do {
- if (efi_dp_match(dp, obj_dp) == 0) {
- if (rem) {
- /*
- * Allow partial matches, but inform
- * the caller.
- */
- *rem = ((void *)dp) +
- efi_dp_instance_size(obj_dp);
- return efiobj;
- } else {
- /* Only return on exact matches */
- if (efi_dp_instance_size(obj_dp) ==
- dp_size)
- return efiobj;
- }
+ struct udevice *protocol;
+ struct efi_handler *handler;
+ struct efi_device_path *obj_dp;
+ efi_status_t ret;
+
+ ret = efi_search_protocol(dev, &efi_guid_device_path, &protocol);
+ if (ret != EFI_SUCCESS)
+ return 0;
+
+ handler = protocol->uclass_platdata;
+ obj_dp = handler->protocol_interface;
+ do {
+ if (efi_dp_match(dp, obj_dp) == 0) {
+ if (rem) {
+ /*
+ * Allow partial matches, but inform
+ * the caller.
+ */
+ *rem = ((void *)dp) +
+ efi_dp_instance_size(obj_dp);
+ param->dev = dev;
+ return 1;
}
- obj_dp = shorten_path(efi_dp_next(obj_dp));
- } while (short_path && obj_dp);
- }
+ /* Only return on exact matches */
+ if (efi_dp_instance_size(obj_dp) == dp_size) {
+ param->dev = dev;
+ return 1;
+ }
+ }
+
+ obj_dp = shorten_path(efi_dp_next(obj_dp));
+ } while (short_path && obj_dp);
+
+ return 0;
+}
+
+static struct udevice *find_obj(struct efi_device_path *dp, bool short_path,
+ struct efi_device_path **rem)
+{
+ struct dp_param dp_param;
+ efi_status_t ret;
+
+ ret = efi_foreach_dev(find_obj_cb, &dp_param);
+ if (ret)
+ return NULL;
- return NULL;
+ return dp_param.dev;
}
/*
* Find an efiobj from device-path, if 'rem' is not NULL, returns the
* remaining part of the device path after the matched object.
*/
-struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
- struct efi_device_path **rem)
+efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
+ struct efi_device_path **rem)
{
- struct efi_object *efiobj;
+ struct udevice *dev;
/* Search for an exact match first */
- efiobj = find_obj(dp, false, NULL);
+ dev = find_obj(dp, false, NULL);
/* Then for a fuzzy match */
- if (!efiobj)
- efiobj = find_obj(dp, false, rem);
+ if (!dev)
+ dev = find_obj(dp, false, rem);
/* And now for a fuzzy short match */
- if (!efiobj)
- efiobj = find_obj(dp, true, rem);
+ if (!dev)
+ dev = find_obj(dp, true, rem);
- return efiobj;
+ return dev;
}
/*
@@ -992,3 +1015,30 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
return EFI_SUCCESS;
}
+
+extern
+char *efi_convert_device_path_to_str(struct efi_device_path *device_path,
+ bool display_only,
+ bool allow_shortcuts);
+
+static int efi_device_path_probe(struct udevice *dev)
+{
+ struct efi_handler *handler;
+ struct efi_device_path *dp;
+ char *name;
+
+ handler = dev->uclass_platdata;
+ dp = handler->protocol_interface;
+ name = efi_convert_device_path_to_str(dp, true, true);
+ device_set_name(dev, name);
+
+ /* TODO: free at unprobe */
+
+ return 0;
+}
+
+U_BOOT_DRIVER(efi_device_path) = {
+ .name = "efi_device_path",
+ .id = UCLASS_EFI_PROTOCOL,
+ .probe = efi_device_path_probe,
+};
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index e219f84b28d2..3d518000eb59 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -6,6 +6,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <efi_loader.h>
#define MAC_OUTPUT_LEN 22
@@ -295,6 +296,47 @@ out:
return text;
}
+/* Temprarily used in probe() for device path protocol driver */
+char *efi_convert_device_path_to_str(struct efi_device_path *device_path,
+ bool display_only,
+ bool allow_shortcuts)
+{
+ char *text = NULL;
+ char buffer[MAX_PATH_LEN];
+ char *str = buffer;
+
+ if (!device_path)
+ goto out;
+
+ while (device_path &&
+ str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) {
+ if (display_only) {
+ /* Only first 8 characters */
+ struct efi_device_path *next;
+
+ next = efi_dp_next(device_path);
+ if (next) {
+ device_path = next;
+ continue;
+ }
+
+ str = efi_convert_single_device_node_to_text(str,
+ device_path);
+ str[9] = '\0';
+ break;
+ }
+
+ *str++ = '/';
+ str = efi_convert_single_device_node_to_text(str, device_path);
+ device_path = efi_dp_next(device_path);
+ }
+
+ text = strdup(buffer);
+
+out:
+ return text;
+}
+
/*
* This function implements the ConvertDevicePathToText service of the
* EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
@@ -344,3 +386,16 @@ const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
.convert_device_node_to_text = efi_convert_device_node_to_text,
.convert_device_path_to_text = efi_convert_device_path_to_text,
};
+
+static int efi_device_path_to_text_probe(struct udevice *dev)
+{
+ device_set_name(dev, "DEVICE_PATH_TO_TEXT");
+
+ return 0;
+}
+
+U_BOOT_DRIVER(efi_device_path_to_text) = {
+ .name = "efi_device_path_to_text",
+ .id = UCLASS_EFI_PROTOCOL,
+ .probe = efi_device_path_to_text_probe,
+};
diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c
index 94015329c8cb..7d7f0c46b18f 100644
--- a/lib/efi_loader/efi_device_path_utilities.c
+++ b/lib/efi_loader/efi_device_path_utilities.c
@@ -6,6 +6,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <efi_loader.h>
const efi_guid_t efi_guid_device_path_utilities_protocol =
@@ -197,3 +198,16 @@ const struct efi_device_path_utilities_protocol efi_device_path_utilities = {
.is_device_path_multi_instance = is_device_path_multi_instance,
.create_device_node = create_device_node,
};
+
+static int efi_device_path_utils_probe(struct udevice *dev)
+{
+ device_set_name(dev, "DEVICE_PATH_UTILITIES");
+
+ return 0;
+}
+
+U_BOOT_DRIVER(efi_device_path_utils) = {
+ .name = "efi_device_path_utils",
+ .id = UCLASS_EFI_PROTOCOL,
+ .probe = efi_device_path_utils_probe,
+};
--
2.19.1
More information about the U-Boot
mailing list