From 4b3ca62138585c1ff6d4aa0663d5ae1a470a985c Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Mon, 6 Sep 2021 21:39:13 +0530 Subject: [PATCH] msm: mhi_dev: Ensure the flush list is empty for a stopped channel If a channel gets stopped, while there are some outstanding requests/ transfers with IPA, then we simply ignore the completion from IPA. But we must have already added the transfer-completion-event to the flush list before submitting the transfer to IPA. There is a possibility that we flush these stale events along with new flush events (for new requests) when the channel gets re-started. This un-intentional completion event can lead to out-of-sequence events at the host. So while stopping a channel, ensure all elements in the flush list of that channel are discarded and the flush list is empty. Change-Id: I04445b1f9f4d2d4fce0b8a96277517de14481ead Signed-off-by: Veerabhadrarao Badiganti --- drivers/platform/msm/mhi_dev/mhi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index 2bfa406cb18c..3409164d3f4f 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -1841,6 +1841,8 @@ static void mhi_dev_process_reset_cmd(struct mhi_dev *mhi, int ch_id) int rc = 0; struct mhi_dev_channel *ch; struct mhi_addr host_addr; + struct event_req *itr, *tmp; + unsigned long flags; rc = mhi_dev_mmio_disable_chdb_a7(mhi, ch_id); if (rc) { @@ -1855,6 +1857,20 @@ static void mhi_dev_process_reset_cmd(struct mhi_dev *mhi, int ch_id) } ch = &mhi->ch[ch_id]; + mhi_log(MHI_MSG_VERBOSE, "Processing reset cmd for ch%d\n", ch_id); + /* + * Ensure that the completions that are present in the flush list are + * removed from the list and discarded before stopping the channel. + * Otherwise, those stale events may get flushed along with a valid + * event in the next flush operation. + */ + spin_lock_irqsave(&mhi_ctx->lock, flags); + list_for_each_entry_safe(itr, tmp, &ch->flush_event_req_buffers, list) { + list_del(&itr->list); + kfree(itr); + } + spin_unlock_irqrestore(&mhi_ctx->lock, flags); + /* hard stop and set the channel to stop */ mhi->ch_ctx_cache[ch_id].ch_state = MHI_DEV_CH_STATE_DISABLED;