[{"id":1760945,"web_url":"http://patchwork.ozlabs.org/comment/1760945/","msgid":"<CAPnjgZ3dWzHTgsRS36M+kn6NSRaeeMda5y3aPBRxDmiJnW7oFw@mail.gmail.com>","list_archive_url":null,"date":"2017-08-31T12:51:43","subject":"Re: [U-Boot] [PATCH 10/23] efi_loader: open_info in OpenProtocol","submitter":{"id":6170,"url":"http://patchwork.ozlabs.org/api/people/6170/","name":"Simon Glass","email":"sjg@chromium.org"},"content":"Hi Heinrich,\n\nOn 27 August 2017 at 06:53, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:\n> efi_open_protocol and close_protocol have to keep track of\n> opened protocols.\n>\n> So we add an array open_info to each protocol of each handle.\n>\n> OpenProtocol has enter the agent and controller handle\n> information into this array.\n>\n> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>\n> ---\n>  include/efi_loader.h          |   1 +\n>  lib/efi_loader/efi_boottime.c | 130 +++++++++++++++++++++++++++++++-----------\n>  2 files changed, 99 insertions(+), 32 deletions(-)\n>\n\nReviewed-by: Simon Glass <sjg@chromium.org>\n\nPlease see below.\n\n> diff --git a/include/efi_loader.h b/include/efi_loader.h\n> index 193fca24ce..2c3360534b 100644\n> --- a/include/efi_loader.h\n> +++ b/include/efi_loader.h\n> @@ -87,6 +87,7 @@ extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;\n>  struct efi_handler {\n>         const efi_guid_t *guid;\n>         void *protocol_interface;\n> +       struct efi_open_protocol_info_entry open_info[4];\n>  };\n>\n>  /*\n> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c\n> index a483b827cd..294bc1f138 100644\n> --- a/lib/efi_loader/efi_boottime.c\n> +++ b/lib/efi_loader/efi_boottime.c\n> @@ -1152,24 +1152,111 @@ static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value)\n>         memset(buffer, value, size);\n>  }\n>\n> +static efi_status_t efi_protocol_open(\n> +                       struct efi_handler *protocol,\n> +                       void **protocol_interface, void *agent_handle,\n> +                       void *controller_handle, uint32_t attributes)\n> +{\n> +       bool opened_exclusive = false;\n> +       bool opened_by_driver = false;\n> +       int i;\n> +       struct efi_open_protocol_info_entry *open_info;\n> +       struct efi_open_protocol_info_entry *match = NULL;\n> +\n> +       if (attributes !=\n> +           EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\n> +               *protocol_interface = NULL;\n> +       }\n> +\n> +       for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {\n> +               open_info = &protocol->open_info[i];\n> +\n> +               if (!open_info->open_count)\n> +                       continue;\n> +               if (open_info->agent_handle == agent_handle) {\n> +                       if ((attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) &&\n> +                           (open_info->attributes == attributes))\n> +                               return EFI_ALREADY_STARTED;\n> +                       if (open_info->controller_handle == controller_handle)\n> +                               match = open_info;\n> +               }\n> +               if (open_info->attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE)\n> +                       opened_exclusive = true;\n> +       }\n> +\n> +       if (attributes &\n> +           (EFI_OPEN_PROTOCOL_EXCLUSIVE | EFI_OPEN_PROTOCOL_BY_DRIVER) &&\n> +           opened_exclusive)\n> +               return EFI_ACCESS_DENIED;\n> +\n> +       if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {\n> +               for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {\n\nIs it possible to put this search in a utility function with suitable\nparameters and call it? This function is very long.\n\n> +                       open_info = &protocol->open_info[i];\n> +\n> +                       if (!open_info->open_count)\n> +                               continue;\n> +                       if (open_info->attributes ==\n> +                                       EFI_OPEN_PROTOCOL_BY_DRIVER)\n> +                               EFI_CALL(efi_disconnect_controller(\n> +                                               open_info->controller_handle,\n> +                                               open_info->agent_handle,\n> +                                               NULL));\n> +               }\n> +               opened_by_driver = false;\n> +               for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {\n> +                       open_info = &protocol->open_info[i];\n> +\n> +                       if (!open_info->open_count)\n> +                               continue;\n> +                       if (open_info->attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)\n> +                               opened_by_driver = true;\n> +               }\n> +               if (opened_by_driver)\n> +                       return EFI_ACCESS_DENIED;\n> +               if (match && !match->open_count)\n> +                       match = NULL;\n> +       }\n> +\n> +       /*\n> +        * Find an empty slot.\n> +        */\n> +       if (!match) {\n> +               for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {\n> +                       open_info = &protocol->open_info[i];\n> +\n> +                       if (!open_info->open_count) {\n> +                               match = open_info;\n> +                               break;\n> +                       }\n> +               }\n> +       }\n> +       if (!match)\n> +               return EFI_OUT_OF_RESOURCES;\n> +\n> +       match->agent_handle = agent_handle;\n> +       match->controller_handle = controller_handle;\n> +       match->attributes = attributes;\n> +       match->open_count++;\n> +       *protocol_interface = protocol->protocol_interface;\n> +\n> +       return EFI_SUCCESS;\n> +}\n> +\n>  static efi_status_t EFIAPI efi_open_protocol(\n>                         void *handle, efi_guid_t *protocol,\n>                         void **protocol_interface, void *agent_handle,\n>                         void *controller_handle, uint32_t attributes)\n>  {\n> -       struct list_head *lhandle;\n> -       int i;\n> +       struct efi_handler *handler;\n>         efi_status_t r = EFI_INVALID_PARAMETER;\n>\n>         EFI_ENTRY(\"%p, %p, %p, %p, %p, 0x%x\", handle, protocol,\n>                   protocol_interface, agent_handle, controller_handle,\n>                   attributes);\n>\n> -       if (!handle || !protocol ||\n> -           (!protocol_interface && attributes !=\n> -            EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {\n> +       if (!protocol_interface && attributes !=\n> +           EFI_OPEN_PROTOCOL_TEST_PROTOCOL)\n>                 goto out;\n> -       }\n>\n>         switch (attributes) {\n>         case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:\n> @@ -1191,33 +1278,12 @@ static efi_status_t EFIAPI efi_open_protocol(\n>                 goto out;\n>         }\n>\n> -       list_for_each(lhandle, &efi_obj_list) {\n> -               struct efi_object *efiobj;\n> -               efiobj = list_entry(lhandle, struct efi_object, link);\n> -\n> -               if (efiobj->handle != handle)\n> -                       continue;\n> -\n> -               for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {\n> -                       struct efi_handler *handler = &efiobj->protocols[i];\n> -                       const efi_guid_t *hprotocol = handler->guid;\n> -                       if (!hprotocol)\n> -                               continue;\n> -                       if (!guidcmp(hprotocol, protocol)) {\n> -                               if (attributes !=\n> -                                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\n> -                                       *protocol_interface =\n> -                                               handler->protocol_interface;\n> -                               }\n> -                               r = EFI_SUCCESS;\n> -                               goto out;\n> -                       }\n> -               }\n> -               goto unsupported;\n> -       }\n> +       r = efi_search_protocol(handle, protocol, &handler);\n> +       if (r != EFI_SUCCESS)\n> +               goto out;\n>\n> -unsupported:\n> -       r = EFI_UNSUPPORTED;\n> +       r = efi_protocol_open(handler, protocol_interface, agent_handle,\n> +                             controller_handle, attributes);\n>  out:\n>         return EFI_EXIT(r);\n>  }\n> --\n> 2.14.1\n>","headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=google.com header.i=@google.com\n\theader.b=\"ATvCLg8z\"; \n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"SfIYuulG\"; dkim-atps=neutral"],"Received":["from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xjj9H6sM1z9s7g\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 31 Aug 2017 22:58:27 +1000 (AEST)","by lists.denx.de (Postfix, from userid 105)\n\tid 9EBADC21D93; Thu, 31 Aug 2017 12:53:09 +0000 (UTC)","from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 6D07CC21D09;\n\tThu, 31 Aug 2017 12:52:25 +0000 (UTC)","by lists.denx.de (Postfix, from userid 105)\n\tid DC310C21D90; Thu, 31 Aug 2017 12:52:09 +0000 (UTC)","from mail-qt0-f174.google.com (mail-qt0-f174.google.com\n\t[209.85.216.174])\n\tby lists.denx.de (Postfix) with ESMTPS id B575FC21DDA\n\tfor <u-boot@lists.denx.de>; Thu, 31 Aug 2017 12:52:05 +0000 (UTC)","by mail-qt0-f174.google.com with SMTP id v20so2356788qtg.3\n\tfor <u-boot@lists.denx.de>; Thu, 31 Aug 2017 05:52:05 -0700 (PDT)","by 10.200.28.106 with HTTP; Thu, 31 Aug 2017 05:51:43 -0700 (PDT)"],"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_NONE,\n\tRCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,\n\tT_DKIM_INVALID autolearn=unavailable\n\tautolearn_force=no version=3.4.0","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=20161025; \n\th=mime-version:sender:in-reply-to:references:from:date:message-id\n\t:subject:to:cc;\n\tbh=NOiveuCULuW4o0kaQ+f+sB0cCO9u++GiqHSD5vwqT9Q=;\n\tb=ATvCLg8zibLrstHfL+OELUeVzBT86rLHOwPWzTlLxnhq61SpLWefATXIqGGCSb5Mg9\n\tBevAKFWhLsjpvTH8KLUniMy2pJEJapyno74C4AOJbxUhcYeTVbdRFJrLYwTpQdiYNdz5\n\txyId4HiiFD///F4MHdgP1xU6XErAZoqnpwdHKT/kb3ZjeqDuSCZJxR4QjHhqyJdllrmh\n\tuIqGEZEhrdzi6sFQC35Lfmr4se8fNTjfoxgudii/Kb462SHqnpor3PyKRCVTPfsixHmx\n\toVfq7NdM/I0+h7qTLKGdr9YHidxE+eolQcms3cFj8kM2xWGsvQDoYKhcvBNYiPY22r90\n\tVePQ==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:sender:in-reply-to:references:from:date:message-id\n\t:subject:to:cc;\n\tbh=NOiveuCULuW4o0kaQ+f+sB0cCO9u++GiqHSD5vwqT9Q=;\n\tb=SfIYuulG2O6jC3V99QyF4qe8k1+fuK/ubxBAnxK20fckaBsklP2G6u1SOVyk2XVfvp\n\tBtYFXOlCY2L5/GjMsJhzGzDONNAeTq+uknrQimprSNypTsHamHsvOI1bVko7jENcjBgb\n\tnEyHT8CFrJdjNf37JOObmbzIsYe6oc1MSezHE="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:sender:in-reply-to:references:from\n\t:date:message-id:subject:to:cc;\n\tbh=NOiveuCULuW4o0kaQ+f+sB0cCO9u++GiqHSD5vwqT9Q=;\n\tb=XINlUqDhJchvZJZOX9+uarBROk9V9kK0VYNkrcno4fTN3AOjZZF3Z26nagMtXUGL0f\n\tpd8KGwjb6T9PKuDK6z8K5f4+jfi3cyByEcEAu0nD3JF1jcKJoyfbLUb8vL4ckkhbv5B0\n\tRozIF+l/OomzI2kInPeuRt/LA/C8sEsfTFxlfZjXARri2hKdUm3Ywij3s2rGFMwv2fgU\n\tSljDX0uBXzv2HAUcNAAY7qhZ9laYsPPyf1LszB/VlxnnMSfmEKNvmUrR4R6kK6go4gLp\n\t8eaiQZdKw/o0CGTyEOVWx8Y48r1ZqT5XHYUSk0Kra2MZF4CjH0AOR5YO7A2unnXCR5OR\n\txkuQ==","X-Gm-Message-State":"AHYfb5gyt65k9jYMkMxD6IiOL+FWsxpGPalEoz0fmHgRWmrKUcaTj06d\n\t07NRNfY46JTc/4h9B/8q1ysSZAr6YwYI","X-Google-Smtp-Source":"ADKCNb4sZZpxBRoLNMaYe+qyb3hvT+PYA2Kr4DGgrMqhxnXrxyCmTy87fETtgTycY5BgVzKmMKmu/SDLZbFdvQX0mI4=","X-Received":"by 10.237.36.211 with SMTP id u19mr6686023qtc.122.1504183924404; \n\tThu, 31 Aug 2017 05:52:04 -0700 (PDT)","MIME-Version":"1.0","In-Reply-To":"<20170826225328.7550-1-xypron.glpk@gmx.de>","References":"<20170826225110.7381-1-xypron.glpk@gmx.de>\n\t<20170826225328.7550-1-xypron.glpk@gmx.de>","From":"Simon Glass <sjg@chromium.org>","Date":"Thu, 31 Aug 2017 20:51:43 +0800","X-Google-Sender-Auth":"I95TliVl1CBYgU5lUGAAGV3kmKU","Message-ID":"<CAPnjgZ3dWzHTgsRS36M+kn6NSRaeeMda5y3aPBRxDmiJnW7oFw@mail.gmail.com>","To":"Heinrich Schuchardt <xypron.glpk@gmx.de>","Cc":"U-Boot Mailing List <u-boot@lists.denx.de>","Subject":"Re: [U-Boot] [PATCH 10/23] efi_loader: open_info in OpenProtocol","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.18","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<http://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>"}}]