[Skiboot] [PATCH V2 20/21] core/pldm: Add file io write request
Abhishek SIngh Tomar
abhishek at linux.ibm.com
Wed Mar 16 20:14:42 AEDT 2022
Hello Christophe
In function write_file_req(uint32_t file_handle, uint32_t file_length,
void *buf, uint32_t offset, uint64_t size)
> + if ((!size) || (size > file_length))
> + return OPAL_PARAMETER;
I am Unable to understand why file length need to be > size in case of
write.
Regards
Abhishek Singh Tomar
On Fri, Mar 04, 2022 at 02:11:53PM +0100, Christophe Lombard wrote:
> Send/receive a PLDM WriteFile request message.
>
> Due to maximum transfer size for PLDM protocol, we have to send several
> write requests, if necessary.
>
> Signed-off-by: Christophe Lombard <clombard at linux.vnet.ibm.com>
> ---
> core/pldm/pldm-file-io-requests.c | 130 ++++++++++++++++++++++++++++++
> core/pldm/pldm.h | 4 +
> 2 files changed, 134 insertions(+)
>
> diff --git a/core/pldm/pldm-file-io-requests.c b/core/pldm/pldm-file-io-requests.c
> index ce4297d0..a86527c0 100644
> --- a/core/pldm/pldm-file-io-requests.c
> +++ b/core/pldm/pldm-file-io-requests.c
> @@ -163,6 +163,136 @@ int pldm_file_io_read_file(uint32_t file_handle,
> buf, offset, size);
> }
>
> +/*
> + * Send/receive a PLDM WriteFile request message.
> + */
> +static int write_file_req(uint32_t file_handle, uint32_t file_length,
> + void *buf, uint32_t offset, uint64_t size)
> +{
> + void *response_msg, *current_ptr, *payload_data;
> + uint32_t total_write, resp_length, request_length;
> + size_t response_len, payload_len;
> + uint8_t completion_code;
> + int num_transfers;
> + char *request_msg;
> + int rc, i;
> +
> + struct pldm_write_file_req file_req = {
> + .file_handle = file_handle,
> + .offset = offset,
> + .length = size
> + };
> +
> + if (!file_length)
> + return OPAL_PARAMETER;
> +
> + if ((!size) || (size > file_length))
> + return OPAL_PARAMETER;
> +
> + if ((offset) && (offset > file_length))
> + return OPAL_PARAMETER;
> +
> + request_length = sizeof(struct pldm_msg_hdr) +
> + sizeof(struct pldm_write_file_req) +
> + size;
> + request_msg = malloc(request_length);
> +
> + payload_data = ((struct pldm_msg *)request_msg)->payload
> + + sizeof(file_req.file_handle)
> + + sizeof(file_req.offset)
> + + sizeof(file_req.length);
> + memcpy(payload_data, buf, size);
> + current_ptr = payload_data;
> + num_transfers = 1;
> + total_write = 0;
> +
> + if (size > MAX_TRANSFER_SIZE_BYTES) {
> + num_transfers = (size + MAX_TRANSFER_SIZE_BYTES - 1) /
> + MAX_TRANSFER_SIZE_BYTES;
> + file_req.length = MAX_TRANSFER_SIZE_BYTES;
> + }
> +
> + prlog(PR_TRACE, "%s - file_handle: %d, offset: 0x%x, size: 0x%x, num_transfers: %d\n",
> + __func__, file_handle, file_req.offset,
> + file_req.length, num_transfers);
> +
> + for (i = 0; i < num_transfers; i++) {
> + file_req.offset = offset + (i * MAX_TRANSFER_SIZE_BYTES);
> +
> + /* Encode the file request */
> + rc = encode_write_file_req(
> + DEFAULT_INSTANCE_ID,
> + file_req.file_handle,
> + file_req.offset,
> + file_req.length,
> + (struct pldm_msg *)request_msg);
> + if (rc != PLDM_SUCCESS) {
> + prlog(PR_ERR, "Encode WriteFileReq Error (rc: %d)\n",
> + rc);
> + free(request_msg);
> + return OPAL_PARAMETER;
> + }
> +
> + /* Send and get the response message bytes */
> + rc = pldm_do_request(BMC_EID, request_msg,
> + request_length - 1,
> + &response_msg, &response_len);
> + if (rc) {
> + prlog(PR_ERR, "PLDM: Communication Error (req:"
> + "WriteFileReq, rc: %d)\n", rc);
> + free(request_msg);
> + return OPAL_PARAMETER;
> + }
> +
> + /* Decode the message */
> + payload_len = response_len - sizeof(struct pldm_msg_hdr);
> + rc = decode_write_file_resp(
> + response_msg,
> + payload_len,
> + &completion_code,
> + &resp_length);
> + if (rc != PLDM_SUCCESS || completion_code != PLDM_SUCCESS) {
> + prlog(PR_ERR, "Decode WriteFileResp Error (rc: %d, cc: %d)\n",
> + rc, completion_code);
> + free(request_msg);
> + return OPAL_PARAMETER;
> + }
> +
> + if (resp_length == 0) {
> + free(response_msg);
> + break;
> + }
> +
> + total_write += resp_length;
> + current_ptr += resp_length;
> + free(response_msg);
> +
> + if (total_write == size)
> + break;
> + else if (resp_length != file_req.length) {
> + /* end of file */
> + break;
> + } else if (MAX_TRANSFER_SIZE_BYTES > (size - total_write))
> + file_req.length = size - total_write;
> + }
> +
> + free(request_msg);
> +
> + return OPAL_SUCCESS;
> +}
> +
> +int pldm_file_io_write_file(uint32_t file_handle,
> + uint32_t file_length,
> + void *buf, uint32_t offset,
> + uint64_t size)
> +{
> + if (!file_io_ready)
> + return OPAL_PARAMETER;
> +
> + return write_file_req(file_handle, file_length,
> + buf, offset, size);
> +}
> +
> /*
> * Send/receive a PLDM GetFileTable request message.
> * The file table contains the list of files available and
> diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
> index da572a6a..e7a175f5 100644
> --- a/core/pldm/pldm.h
> +++ b/core/pldm/pldm.h
> @@ -55,6 +55,10 @@ int pldm_file_io_read_file(uint32_t file_handle,
> uint32_t file_length,
> void *buf, uint32_t offset,
> uint64_t size);
> +int pldm_file_io_write_file(uint32_t file_handle,
> + uint32_t file_length,
> + void *buf, uint32_t offset,
> + uint64_t size);
> int pldm_file_io_init(void);
>
> int pldm_fru_get_record_by_option(uint16_t fru_table_handle,
> --
> 2.35.1
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
More information about the Skiboot
mailing list