From patchwork Fri Feb 8 08:15:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1038515 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="v8aT+hba"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43wp4D2y1hz9sML for ; Fri, 8 Feb 2019 19:19:08 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id EF5DDC21FC6; Fri, 8 Feb 2019 08:17:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C32AEC2200E; Fri, 8 Feb 2019 08:15:24 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1311FC2201F; Fri, 8 Feb 2019 08:15:15 +0000 (UTC) Received: from mail-yw1-f67.google.com (mail-yw1-f67.google.com [209.85.161.67]) by lists.denx.de (Postfix) with ESMTPS id 9CBE7C21FFB for ; Fri, 8 Feb 2019 08:15:11 +0000 (UTC) Received: by mail-yw1-f67.google.com with SMTP id p17so1079579ywg.0 for ; Fri, 08 Feb 2019 00:15:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=70GhFM5C1aInVUl7a7NnR/KlhNrsWchA0/1uDNANpJw=; b=v8aT+hbaiEBXcdTq/CN5+kAZ7Cmf1FSyfYxFeHORP+dwffy+ggXL5lNuwB4+8858dj Ej2oQc8jikGhT3ZEpK0LyMHm0ryTOphn8qRsV0leQA/g385JrLZEq9svAdAZ1dIMRvo7 kFpCsHVt1iwk7ToWMh1w3pfBJ5y+ppBPG/bUifk9I5HwxcUb+1ct3pKvTdcHNM2oRlIR EdrzmPFvmuBILOf8d0lNctl8ho9OiCu4mTH6szfVTegrrMM95xbF/P6hxVYFLr8l0700 PuI4hWgVZ4Jt8fG3f3kamBcExhs98+3MvIezExeUtBVZnTcqrzVjwzZ2h7zA0MYZL1tr urjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=70GhFM5C1aInVUl7a7NnR/KlhNrsWchA0/1uDNANpJw=; b=l7nhVDtus4abp/n4WTpFqi82K6+JslWPc66QSlCYczOYdHEwzlN+FKlzYWBvER5+v3 HXKVpJVpDlsGDFJ3cPytkZa8j8qHQ5bOerNGrKF5sKHEamNTHT38aRsxgZ8E34yxhAGE K3o7U4nAswF2puGmI0E7xcUSdiHypwyTJTAjZuoIPE94rZBiAFnCII8gN7p6nnjwM+1c Neg13CSE7JpvwrtgYO/nIpwKr8grUCccC6XU0ltjvK/AfP9858ltd8nH81FpaPbjHlwy isGAKpa/SfxppEKZ0KPkRGIH/GfZZN9y9lNSIny5VvC1Ch0dWD/mr03bHP9eYEJP4tjt nZOw== X-Gm-Message-State: AHQUAua7t8mg+/QoleC6GzmDeaiKubCFvnggVUTTbO8qM/WIttxanHMk S3Gp67J5HKSYjRUJIiThWee3kg== X-Google-Smtp-Source: AHgI3IbmGL/VDHMhXTakuGJyQ16+whMXvWYUuA94YSLkD9T+mxj6ohK3/0baRdZORiDuSroZnjnn9Q== X-Received: by 2002:a81:5d55:: with SMTP id r82mr8631663ywb.213.1549613710542; Fri, 08 Feb 2019 00:15:10 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id r124sm511292ywb.39.2019.02.08.00.15.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Feb 2019 00:15:10 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de, xypron.glpk@gmx.de, sjg@chromium.org Date: Fri, 8 Feb 2019 17:15:33 +0900 Message-Id: <20190208081542.2813-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190208081542.2813-1-takahiro.akashi@linaro.org> References: <20190208081542.2813-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [RFC v2 06/15] efi_loader: device path: convert efi_device_path to DM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Signed-off-by: AKASHI Takahiro --- 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 +#include #include #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 +#include #include 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, +};