<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <br>
    <br>
    <div class="moz-cite-prefix">Le 12/04/2023 à 17:49, Frederic Barrat
      a écrit :<br>
    </div>
    <blockquote type="cite"
      cite="mid:c1641dfd-d4ec-5e85-e318-82bdd0d09226@linux.ibm.com">
      <br>
      <br>
      On 13/09/2022 12:27, Christophe Lombard wrote:
      <br>
      <blockquote type="cite">Send/receive a PLDM ReadFile request
        message.
        <br>
        <br>
        Due to maximum transfer size for PLDM protocol, we have to send
        several
        <br>
        read requests, if necessary.
        <br>
        <br>
        Signed-off-by: Christophe Lombard
        <a class="moz-txt-link-rfc2396E" href="mailto:clombard@linux.vnet.ibm.com"><clombard@linux.vnet.ibm.com></a>
        <br>
        ---
        <br>
          core/pldm/pldm-file-io-requests.c | 129
        ++++++++++++++++++++++++++++++
        <br>
          core/pldm/pldm.h                  |   2 +
        <br>
          2 files changed, 131 insertions(+)
        <br>
        <br>
        diff --git a/core/pldm/pldm-file-io-requests.c
        b/core/pldm/pldm-file-io-requests.c
        <br>
        index 5eb260d6..48b00ef2 100644
        <br>
        --- a/core/pldm/pldm-file-io-requests.c
        <br>
        +++ b/core/pldm/pldm-file-io-requests.c
        <br>
        @@ -7,6 +7,7 @@
        <br>
          #include <stdio.h>
        <br>
          #include <string.h>
        <br>
          #include <inttypes.h>
        <br>
        +#include <timebase.h>
        <br>
          #include <pldm/ibm/libpldm/file_io.h>
        <br>
          #include "pldm.h"
        <br>
          @@ -33,6 +34,134 @@ static void file_io_init_complete(bool
        success)
        <br>
              file_io_ready = true;
        <br>
          }
        <br>
          +/* maximum currently transfer size for PLDM */
        <br>
        +#define KILOBYTE 1024ul
        <br>
        +#define MAX_TRANSFER_SIZE_BYTES (127 * KILOBYTE + 1)
        <br>
      </blockquote>
      <br>
      <br>
      I didn't find the origin of that limit, especially the odd-looking
      "+1"...
      <br>
      <br>
    </blockquote>
    <span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span
          class="ryNqvb"><br>
          I had read somewhere that the maximum transfer size for PLDM
          is defined as 180K and<br>
          HB has found that the optimal transfer size that doesn't make
          HB crash is (127k + 1) bytes.<br>
        </span></span></span><br>
    <blockquote type="cite"
      cite="mid:c1641dfd-d4ec-5e85-e318-82bdd0d09226@linux.ibm.com">
      <br>
      <blockquote type="cite">+
        <br>
        +/*
        <br>
        + * Send/receive a PLDM ReadFile request message.
        <br>
        + */
        <br>
        +static int read_file_req(uint32_t file_handle, uint32_t
        file_length,
        <br>
        +             void *buf, uint32_t offset, uint64_t size)
        <br>
        +{
        <br>
        +    char request_msg[PKT_SIZE(struct pldm_read_file_req)];
        <br>
        +    size_t response_len, payload_len, file_data_offset;
        <br>
        +    uint8_t completion_code;
        <br>
        +    uint32_t resp_length;
        <br>
        +    uint64_t total_read;
        <br>
        +    void *response_msg;
        <br>
        +    int num_transfers;
        <br>
        +    void *curr_buf;
        <br>
        +    int rc, i;
        <br>
        +
        <br>
        +    struct pldm_read_file_req file_req = {
        <br>
        +        .file_handle = file_handle,
        <br>
        +        .offset = offset,
        <br>
        +        .length = size
        <br>
        +    };
        <br>
        +
        <br>
        +    if (!file_length)
        <br>
        +        return OPAL_PARAMETER;
        <br>
        +
        <br>
        +    if ((!size) || (size > file_length))
        <br>
        +        return OPAL_PARAMETER;
        <br>
        +
        <br>
        +    if ((offset) && ((size + offset) > file_length))
        <br>
        +        return OPAL_PARAMETER;
        <br>
      </blockquote>
      <br>
      <br>
      The last 2 'if' statements should be equivalent to:
      <br>
          if ((!size) || ((size + offset) > file_length))
      <br>
              return OPAL_PARAMETER;
      <br>
      <br>
    </blockquote>
    <br>
    good. Thanks<br>
    <br>
    <blockquote type="cite"
      cite="mid:c1641dfd-d4ec-5e85-e318-82bdd0d09226@linux.ibm.com">
      <br>
      <blockquote type="cite">+
        <br>
        +    num_transfers = 1;
        <br>
        +    curr_buf = buf;
        <br>
        +    total_read = 0;
        <br>
        +
        <br>
        +    if (file_req.length > MAX_TRANSFER_SIZE_BYTES) {
        <br>
        +        num_transfers = (file_req.length +
        MAX_TRANSFER_SIZE_BYTES - 1) /
        <br>
        +                MAX_TRANSFER_SIZE_BYTES;
        <br>
        +        file_req.length = MAX_TRANSFER_SIZE_BYTES;
        <br>
        +    }
        <br>
        +
        <br>
        +    prlog(PR_TRACE, "%s - file_handle: %d, offset: 0x%x, size:
        0x%llx num_transfers: %d\n",
        <br>
        +            __func__, file_handle, file_req.offset,
        <br>
        +            size, num_transfers);
        <br>
        +
        <br>
        +    for (i = 0; i < num_transfers; i++) {
        <br>
        +        file_req.offset = offset + (i *
        MAX_TRANSFER_SIZE_BYTES);
        <br>
        +
        <br>
        +        /* Encode the file request */
        <br>
        +        rc = encode_read_file_req(
        <br>
        +                DEFAULT_INSTANCE_ID,
        <br>
        +                file_req.file_handle,
        <br>
        +                file_req.offset,
        <br>
        +                file_req.length,
        <br>
        +                (struct pldm_msg *)request_msg);
        <br>
        +        if (rc != PLDM_SUCCESS) {
        <br>
        +            prlog(PR_ERR, "Encode ReadFileReq Error, rc: %d\n",
        <br>
        +                      rc);
        <br>
        +            return OPAL_PARAMETER;
        <br>
        +        }
        <br>
        +
        <br>
        +        /* Send and get the response message bytes */
        <br>
        +        rc = pldm_requester_queue_and_wait(
        <br>
        +                    request_msg, sizeof(request_msg),
        <br>
        +                    &response_msg, &response_len);
        <br>
        +        if (rc) {
        <br>
        +            prlog(PR_ERR, "Communication Error, req:
        ReadFileReq, rc: %d\n", rc);
        <br>
        +            return rc;
        <br>
        +        }
        <br>
        +
        <br>
        +        /* Decode the message */
        <br>
        +        payload_len = response_len - sizeof(struct
        pldm_msg_hdr);
        <br>
        +        rc = decode_read_file_resp(
        <br>
        +                response_msg,
        <br>
        +                payload_len,
        <br>
        +                &completion_code,
        <br>
        +                &resp_length,
        <br>
        +                &file_data_offset);
        <br>
        +        if (rc != PLDM_SUCCESS || completion_code !=
        PLDM_SUCCESS) {
        <br>
        +            prlog(PR_ERR, "Decode ReadFileResp Error, rc: %d,
        cc: %d\n",
        <br>
        +                      rc, completion_code);
        <br>
        +            free(response_msg);
        <br>
        +            return OPAL_PARAMETER;
        <br>
        +        }
        <br>
        +
        <br>
        +        if (resp_length == 0) {
        <br>
        +            free(response_msg);
        <br>
        +            break;
        <br>
        +        }
        <br>
        +
        <br>
        +        memcpy(curr_buf,
        <br>
        +               ((struct pldm_msg *)response_msg)->payload +
        file_data_offset,
        <br>
        +               resp_length);
        <br>
        +
        <br>
        +        total_read += resp_length;
        <br>
        +        curr_buf += resp_length;
        <br>
        +        free(response_msg);
        <br>
        +
        <br>
        +        prlog(PR_TRACE, "%s - file_handle: %d, resp_length:
        0x%x, total_read: 0x%llx\n",
        <br>
        +            __func__, file_handle, resp_length, total_read);
        <br>
        +
        <br>
        +        if (total_read == size)
        <br>
      </blockquote>
      <br>
      <br>
      if (total_read >= size) for peace of mind?
      <br>
      <br>
    </blockquote>
    <br>
    right, :-)<br>
    <br>
    <blockquote type="cite"
      cite="mid:c1641dfd-d4ec-5e85-e318-82bdd0d09226@linux.ibm.com">
      <br>
      <blockquote type="cite">+            break;
        <br>
        +        else if (resp_length != file_req.length) {
        <br>
        +            /* end of file */
        <br>
        +            break;
        <br>
        +        } else if (MAX_TRANSFER_SIZE_BYTES > (size -
        total_read))
        <br>
        +            file_req.length = size - total_read;
        <br>
        +
        <br>
        +        time_wait_ms(20);
        <br>
      </blockquote>
      <br>
      <br>
      Any reason for that 20 ms delay?
      <br>
      <br>
    </blockquote>
    <br>
    Really, I don't remember. May be, we could remove this delay.<br>
    <br>
    <blockquote type="cite"
      cite="mid:c1641dfd-d4ec-5e85-e318-82bdd0d09226@linux.ibm.com"> 
      Fred
      <br>
      <br>
    </blockquote>
    <br>
  </body>
</html>