Signed-off-by: AKASHI Takahiro <[email protected]>
---
 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

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to