firmware: arm_scmi: Add missing Rx size re-initialisation
authorSudeep Holla <sudeep.holla@arm.com>
Mon, 12 Oct 2020 13:26:24 +0000 (14:26 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Tue, 13 Oct 2020 09:01:47 +0000 (10:01 +0100)
Few commands provide the list of description partially and require
to be called consecutively until all the descriptors are fetched
completely. In such cases, we don't release the buffers and reuse
them for consecutive transmits.

However, currently we don't reset the Rx size which will be set as
per the response for the last transmit. This may result in incorrect
response size being interpretted as the firmware may repond with size
greater than the one set but we read only upto the size set by previous
response.

Let us reset the receive buffer size to max possible in such cases as
we don't know the exact size of the response.

Link:  https://lore.kernel.org/r/20201012141746.32575-1-sudeep.holla@arm.com
Fixes: b6f20ff8bd94 ("firmware: arm_scmi: add common infrastructure and support for base protocol")
Reported-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/base.c
drivers/firmware/arm_scmi/clock.c
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/sensors.c

index 9853bd3c4d456b490855a36425935b29378427c6..017e5d8bd869a752d14bd7cdf58032e9d8a96787 100644 (file)
@@ -197,6 +197,8 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
                        protocols_imp[tot_num_ret + loop] = *(list + loop);
 
                tot_num_ret += loop_num_ret;
+
+               scmi_reset_rx_to_maxsz(handle, t);
        } while (loop_num_ret);
 
        scmi_xfer_put(handle, t);
index c1cfe3ee3d55a826ff1f97ca8156873a61c212ca..4645677d86f1b1648bccfb99c9f88a2393a98dff 100644 (file)
@@ -192,6 +192,8 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
                }
 
                tot_rate_cnt += num_returned;
+
+               scmi_reset_rx_to_maxsz(handle, t);
                /*
                 * check for both returned and remaining to avoid infinite
                 * loop due to buggy firmware
index 37fb583f1bf5f9e1362b121ca6eb9796345009fc..65063fa948d412e41b81aff9489bcfd0802fd8e2 100644 (file)
@@ -147,6 +147,8 @@ int scmi_do_xfer_with_response(const struct scmi_handle *h,
                               struct scmi_xfer *xfer);
 int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
                       size_t tx_size, size_t rx_size, struct scmi_xfer **p);
+void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
+                           struct scmi_xfer *xfer);
 int scmi_handle_put(const struct scmi_handle *handle);
 struct scmi_handle *scmi_handle_get(struct device *dev);
 void scmi_set_handle(struct scmi_device *scmi_dev);
index c5dea87edf8f2c61b6be519232434be9a91e6f50..3dfd8b6a0ebf789089c17d87a3348619fbccfc27 100644 (file)
@@ -402,6 +402,14 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
        return ret;
 }
 
+void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
+                           struct scmi_xfer *xfer)
+{
+       struct scmi_info *info = handle_to_scmi_info(handle);
+
+       xfer->rx.len = info->desc->max_msg_size;
+}
+
 #define SCMI_MAX_RESPONSE_TIMEOUT      (2 * MSEC_PER_SEC)
 
 /**
index ed475b40bd083a0d20424977cfa223633e1199f0..82fb3babff72133f67997491b30beb8a575d87c2 100644 (file)
@@ -304,6 +304,8 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
                }
 
                tot_opp_cnt += num_returned;
+
+               scmi_reset_rx_to_maxsz(handle, t);
                /*
                 * check for both returned and remaining to avoid infinite
                 * loop due to buggy firmware
index 9703cf6356a0452c3af99d608c6ba52febd6c901..b4232d611033e5ff83168bf6a20772bbe6801c88 100644 (file)
@@ -166,6 +166,8 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
                }
 
                desc_index += num_returned;
+
+               scmi_reset_rx_to_maxsz(handle, t);
                /*
                 * check for both returned and remaining to avoid infinite
                 * loop due to buggy firmware