From: Ye Li <ye...@nxp.com>

@protocols is an array of protocol identifiers that are implemented,
excluding the Base protocol. The number of elements of @protocols is
specified by callee-side.

Signed-off-by: Ye Li <ye...@nxp.com>
Signed-off-by: Alice Guo <alice....@nxp.com>
---
 drivers/firmware/scmi/base.c | 24 +++++++++++++++++-------
 include/scmi_protocols.h     |  2 +-
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/scmi/base.c b/drivers/firmware/scmi/base.c
index f4e3974ff5b..3943d90fd40 100644
--- a/drivers/firmware/scmi/base.c
+++ b/drivers/firmware/scmi/base.c
@@ -258,7 +258,7 @@ static int scmi_base_discover_impl_version_int(struct 
udevice *dev,
 static int scmi_base_discover_list_protocols_int(struct udevice *dev,
                                                 u8 **protocols)
 {
-       struct scmi_base_discover_list_protocols_out out;
+       struct scmi_base_discover_list_protocols_out *out;
        int cur;
        struct scmi_msg msg = {
                .protocol_id = SCMI_PROTOCOL_ID_BASE,
@@ -268,7 +268,7 @@ static int scmi_base_discover_list_protocols_int(struct 
udevice *dev,
                .out_msg = (u8 *)&out,
                .out_msg_sz = sizeof(out),
        };
-       u32 num_agents, num_protocols;
+       u32 num_agents, num_protocols, out_size;
        u8 *buf;
        int i, ret;
 
@@ -276,22 +276,31 @@ static int scmi_base_discover_list_protocols_int(struct 
udevice *dev,
        if (ret)
                return ret;
 
+       out_size = sizeof(*out) + sizeof(u32) * (1 + (num_protocols - 1) / 4);
+       out = calloc(1, out_size);
+       if (!out)
+               return -ENOMEM;
+       msg.out_msg = (u8 *)out;
+       msg.out_msg_sz = out_size;
+
        buf = calloc(sizeof(u8), num_protocols);
-       if (!buf)
+       if (!buf) {
+               free(out);
                return -ENOMEM;
+       }
 
        cur = 0;
        do {
                ret = devm_scmi_process_msg(dev, &msg);
                if (ret)
                        goto err;
-               if (out.status) {
-                       ret = scmi_to_linux_errno(out.status);
+               if (out->status) {
+                       ret = scmi_to_linux_errno(out->status);
                        goto err;
                }
 
-               for (i = 0; i < out.num_protocols; i++, cur++)
-                       buf[cur] = out.protocols[i / 4] >> ((i % 4) * 8);
+               for (i = 0; i < out->num_protocols; i++, cur++)
+                       buf[cur] = out->protocols[i / 4] >> ((i % 4) * 8);
        } while (cur < num_protocols);
 
        *protocols = buf;
@@ -299,6 +308,7 @@ static int scmi_base_discover_list_protocols_int(struct 
udevice *dev,
        return num_protocols;
 err:
        free(buf);
+       free(out);
 
        return ret;
 }
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 519b906b4ce..9046de7e3e7 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -145,7 +145,7 @@ struct scmi_base_discover_impl_version_out {
 struct scmi_base_discover_list_protocols_out {
        s32 status;
        u32 num_protocols;
-       u32 protocols[3];
+       u32 protocols[];
 };
 
 /**

-- 
2.43.0

Reply via email to