From patchwork Sun Nov 26 13:05:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 841385 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=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3yl9Q94w9Qz9s3w for ; Mon, 27 Nov 2017 00:14:57 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 6B9F1C21DC1; Sun, 26 Nov 2017 13:12:38 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL 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 37233C21DE6; Sun, 26 Nov 2017 13:08:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E99E4C21DAA; Sun, 26 Nov 2017 13:07:08 +0000 (UTC) Received: from mout.gmx.net (mout.gmx.net [212.227.15.18]) by lists.denx.de (Postfix) with ESMTPS id A4E58C21DBA for ; Sun, 26 Nov 2017 13:07:04 +0000 (UTC) Received: from workstation4.fritz.box ([94.114.42.150]) by mail.gmx.com (mrgmx003 [212.227.17.184]) with ESMTPSA (Nemesis) id 0LvEZe-1fHtFc39aU-010NXs; Sun, 26 Nov 2017 14:06:54 +0100 From: Heinrich Schuchardt To: Alexander Graf Date: Sun, 26 Nov 2017 14:05:17 +0100 Message-Id: <20171126130523.4993-13-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171126130523.4993-1-xypron.glpk@gmx.de> References: <20171126130523.4993-1-xypron.glpk@gmx.de> X-Provags-ID: V03:K0:YuQgnMKuNKjtlostPyD0s69CAKN7OcFO+gMYJVM3UfJAf6cvff2 NlbFyd9bskBZD+Tr2Gcyt9FKKHmU6M8JMbqX606xfTwcfvVrCDQBEUetijwt4xe4HxHZGag fCfEWqDyyI6lPeoY2NHrbeHv4CCSoDW9fWi42IFMjKaj+eGqrihqTLl3fM8N+qZePf96dll 9iVUp+VNdsk8iltXIbIPg== X-UI-Out-Filterresults: notjunk:1; V01:K0:yiuMNvMLvyE=:gqMfAWhr6xUscG+gWGFwRb vDztrCN4DoNxL+gcBETdG4g1axVfcGWr2KRvKYE/iFaayKoBQBasXZCOf3NmyL4xTfN0O4sU5 L8/Ig7BAkvkIEPsSYvNVyPeU2p5UwwI/KM3yCmQTsssUpXEuZvXuxucJ1BSJ1yCfYd2bGI5pT f3ELLNR6isY/QBr4u+1jlOsG+m/3pdxsNEozmZWKSE4fzsuRqyRItTDr+X5ceVki25Akxm+Oj 6c4ynbnjno1TZQQ87MPfHzEO/WX6d+n9eSJDm7G2t4OkkZSqy5sc0EI8XaAlmV7togTZM3aG3 K3k5PmJnP0+WapZcE59j6d/Zb/NpML1ZUISt700n08DQ49Vy3p2xgZRRKfr0r03qHhBlbJkne 5VV1f+aJm0HHFBvgXvej/g/yZL59JpuD6Jbucq55g9EeC0TR/dT1gLzqzHkXvxDNt6F5RAvIe O4J/tpy2JMPf//rfX9TCz9UigbFpLdFJt2InBIBkXxEEnTmHgs4FHwRcvH0WyvUc6V1oRmV4B ru4f9oDX9fFSXi5BixgXbx09HoeMiAqmw91kH87f1Bi+AVsuhaVEgNUNadWATuPJSUS4v1P7f 0vnfTUQRxYO3YL85dhZNy9vgTNh14qAeaBqce7hHUOcJIuT9wF8xOTW+56djYQYgyyAnaZUrs mz7b+r6HBVLxsoP/YHeFaDE+aiIySukPZBtXKbKoryQ89pQdCqoys7dBERJw8t1TgwAZWvFJa DHQzcMG2tpIchR5xkNkheRm1P4G1xPLswC3NNhIAspCvRqocTbLv5nlYoQTfHEGqSIkpjgc7q SKO9bH70gNUWqm0Z6HzPHKuR8TnFA== Cc: Heinrich Schuchardt , u-boot@lists.denx.de Subject: [U-Boot] [PATCH v3 12/18] efi_loader: manage protocols in a linked list 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Reviewed-by: Simon Glass Signed-off-by: Heinrich Schuchardt --- v3 no change v2 no change --- include/efi_loader.h | 6 ++- lib/efi_loader/efi_boottime.c | 107 ++++++++++++++++++++---------------------- lib/efi_loader/efi_disk.c | 1 + lib/efi_loader/efi_gop.c | 1 + lib/efi_loader/efi_net.c | 1 + 5 files changed, 58 insertions(+), 58 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index e1f0af3496..a73bbc1269 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -101,6 +101,8 @@ extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; * interface (usually a struct with callback functions), this struct maps the * protocol GUID to the respective protocol interface */ struct efi_handler { + /* Link to the list of protocols of a handle */ + struct list_head link; const efi_guid_t *guid; void *protocol_interface; }; @@ -115,8 +117,8 @@ struct efi_handler { struct efi_object { /* Every UEFI object is part of a global object list */ struct list_head link; - /* We support up to 16 "protocols" an object can be accessed through */ - struct efi_handler protocols[16]; + /* The list of protocols */ + struct list_head protocols; /* The object spawner can either use this for data or as identifier */ void *handle; }; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4cc5b1e620..54e9c27db1 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -339,6 +339,7 @@ efi_status_t efi_create_handle(void **handle) return r; memset(obj, 0, sizeof(struct efi_object)); obj->handle = obj; + INIT_LIST_HEAD(&obj->protocols); list_add_tail(&obj->link, &efi_obj_list); *handle = obj; return r; @@ -715,18 +716,17 @@ efi_status_t efi_search_protocol(const void *handle, struct efi_handler **handler) { struct efi_object *efiobj; - size_t i; - struct efi_handler *protocol; + struct list_head *lhandle; if (!handle || !protocol_guid) return EFI_INVALID_PARAMETER; efiobj = efi_search_obj(handle); if (!efiobj) return EFI_INVALID_PARAMETER; - for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { - protocol = &efiobj->protocols[i]; - if (!protocol->guid) - continue; + list_for_each(lhandle, &efiobj->protocols) { + struct efi_handler *protocol; + + protocol = list_entry(lhandle, struct efi_handler, link); if (!guidcmp(protocol->guid, protocol_guid)) { if (handler) *handler = protocol; @@ -750,7 +750,6 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol, struct efi_object *efiobj; struct efi_handler *handler; efi_status_t ret; - size_t i; efiobj = efi_search_obj(handle); if (!efiobj) @@ -761,16 +760,10 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol, handler = calloc(1, sizeof(struct efi_handler)); if (!handler) return EFI_OUT_OF_RESOURCES; - /* Install protocol in first empty slot. */ - for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { - handler = &efiobj->protocols[i]; - if (handler->guid) - continue; - handler->guid = protocol; - handler->protocol_interface = protocol_interface; - return EFI_SUCCESS; - } - return EFI_OUT_OF_RESOURCES; + handler->guid = protocol; + handler->protocol_interface = protocol_interface; + list_add_tail(&handler->link, &efiobj->protocols); + return EFI_SUCCESS; } /* @@ -790,10 +783,10 @@ efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, ret = efi_search_protocol(handle, protocol, &handler); if (ret != EFI_SUCCESS) return ret; - if (handler->protocol_interface != protocol_interface) - return EFI_NOT_FOUND; - handler->guid = NULL; - handler->protocol_interface = NULL; + if (guidcmp(handler->guid, protocol)) + return EFI_INVALID_PARAMETER; + list_del(&handler->link); + free(handler); return EFI_SUCCESS; } @@ -806,17 +799,22 @@ efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, efi_status_t efi_remove_all_protocols(const void *handle) { struct efi_object *efiobj; - struct efi_handler *handler; - size_t i; + struct list_head *lhandle; + struct list_head *pos; efiobj = efi_search_obj(handle); if (!efiobj) return EFI_INVALID_PARAMETER; + list_for_each_safe(lhandle, pos, &efiobj->protocols) { + struct efi_handler *protocol; + efi_status_t ret; - for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { - handler = &efiobj->protocols[i]; - handler->guid = NULL; - handler->protocol_interface = NULL; + protocol = list_entry(lhandle, struct efi_handler, link); + + ret = efi_remove_protocol(handle, protocol->guid, + protocol->protocol_interface); + if (ret != EFI_SUCCESS) + return ret; } return EFI_SUCCESS; } @@ -1171,6 +1169,7 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob if (device_path) info->device_handle = efi_dp_find_obj(device_path, NULL); + INIT_LIST_HEAD(&obj->protocols); list_add_tail(&obj->link, &efi_obj_list); /* * When asking for the device path interface, return @@ -1648,8 +1647,7 @@ static efi_status_t EFIAPI efi_protocols_per_handle(void *handle, { unsigned long buffer_size; struct efi_object *efiobj; - unsigned long i, j; - struct list_head *lhandle; + struct list_head *protocol_handle; efi_status_t r; EFI_ENTRY("%p, %p, %p", handle, protocol_buffer, @@ -1660,36 +1658,33 @@ static efi_status_t EFIAPI efi_protocols_per_handle(void *handle, *protocol_buffer = NULL; *protocol_buffer_count = 0; - list_for_each(lhandle, &efi_obj_list) { - efiobj = list_entry(lhandle, struct efi_object, link); - if (efiobj->handle != handle) - continue; + efiobj = efi_search_obj(handle); + if (!efiobj) + return EFI_EXIT(EFI_INVALID_PARAMETER); - /* Count protocols */ - for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { - if (efiobj->protocols[i].guid) - ++*protocol_buffer_count; - } - /* Copy guids */ - if (*protocol_buffer_count) { - buffer_size = sizeof(efi_guid_t *) * - *protocol_buffer_count; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - buffer_size, - (void **)protocol_buffer); - if (r != EFI_SUCCESS) - return EFI_EXIT(r); - j = 0; - for (i = 0; i < ARRAY_SIZE(efiobj->protocols); ++i) { - if (efiobj->protocols[i].guid) { - (*protocol_buffer)[j] = (void *) - efiobj->protocols[i].guid; - ++j; - } - } + /* Count protocols */ + list_for_each(protocol_handle, &efiobj->protocols) { + ++*protocol_buffer_count; + } + + /* Copy guids */ + if (*protocol_buffer_count) { + size_t j = 0; + + buffer_size = sizeof(efi_guid_t *) * *protocol_buffer_count; + r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size, + (void **)protocol_buffer); + if (r != EFI_SUCCESS) + return EFI_EXIT(r); + list_for_each(protocol_handle, &efiobj->protocols) { + struct efi_handler *protocol; + + protocol = list_entry(protocol_handle, + struct efi_handler, link); + (*protocol_buffer)[j] = (void *)protocol->guid; + ++j; } - break; } return EFI_EXIT(EFI_SUCCESS); diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 1d6cf3122f..af8db40e19 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -224,6 +224,7 @@ static void efi_disk_add_dev(const char *name, goto out_of_memory; /* Hook up to the device list */ + INIT_LIST_HEAD(&diskobj->parent.protocols); list_add_tail(&diskobj->parent.link, &efi_obj_list); /* Fill in object data */ diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c index 7b74d6ef33..498184d754 100644 --- a/lib/efi_loader/efi_gop.c +++ b/lib/efi_loader/efi_gop.c @@ -180,6 +180,7 @@ int efi_gop_register(void) } /* Hook up to the device list */ + INIT_LIST_HEAD(&gopobj->parent.protocols); list_add_tail(&gopobj->parent.link, &efi_obj_list); /* Fill in object data */ diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 8b2f682351..74a67c5365 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -296,6 +296,7 @@ int efi_net_register(void) goto out_of_memory; /* Hook net up to the device list */ + INIT_LIST_HEAD(&netobj->parent.protocols); list_add_tail(&netobj->parent.link, &efi_obj_list); /* Fill in object data */