diff mbox series

[5.4,129/149] firmware: arm_scmi: Reset Rx buffer to max size during async commands

Message ID 20210719144931.866666804@linuxfoundation.org
State New
Headers show
Series None | expand

Commit Message

Greg Kroah-Hartman July 19, 2021, 2:53 p.m. UTC
From: Cristian Marussi <cristian.marussi@arm.com>

[ Upstream commit 0cb7af474e0dbb2f500c67aa62b6db9fafa74de2 ]

During an async commands execution the Rx buffer length is at first set
to max_msg_sz when the synchronous part of the command is first sent.
However once the synchronous part completes the transport layer waits
for the delayed response which will be processed using the same xfer
descriptor initially allocated. Since synchronous response received at
the end of the xfer will shrink the Rx buffer length to the effective
payload response length, it needs to be reset again.

Raise the Rx buffer length again to max_msg_sz before fetching the
delayed response to ensure full response is read correctly from the
shared memory.

Link: https://lore.kernel.org/r/20210601102421.26581-2-cristian.marussi@arm.com
Fixes: 58ecdf03dbb9 ("firmware: arm_scmi: Add support for asynchronous commands and delayed response")
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
[sudeep.holla: moved reset to scmi_handle_response as it could race with
               do_xfer_with_response]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/firmware/arm_scmi/driver.c | 4 ++++
 1 file changed, 4 insertions(+)
diff mbox series

Patch

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 11078199abed..7b6903bad408 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -370,6 +370,10 @@  static void scmi_rx_callback(struct mbox_client *cl, void *m)
 
 	xfer = &minfo->xfer_block[xfer_id];
 
+	/* rx.len could be shrunk in the sync do_xfer, so reset to maxsz */
+	if (msg_type == MSG_TYPE_DELAYED_RESP)
+		xfer->rx.len = info->desc->max_msg_size;
+
 	scmi_dump_header_dbg(dev, &xfer->hdr);
 
 	scmi_fetch_response(xfer, mem);