msm: mhi_dev: check for error during ring processing

The change is to check for error code from cmd processing in case
of db pending cases, to avoid rd_offset increment.

Change-Id: If213297fe02ec1087bfab572f5af97b1e7bb5791
Signed-off-by: Subramanian Ananthanarayanan <skananth@codeaurora.org>
Signed-off-by: Gauri Joshi <gaurjosh@codeaurora.org>
This commit is contained in:
Subramanian Ananthanarayanan 2021-03-09 15:06:45 +05:30 • committed by Gauri Joshi
commit ec8cdae293
3 changed files with 28 additions and 21 deletions

View file

@ -1872,7 +1872,7 @@ static void mhi_dev_process_reset_cmd(struct mhi_dev *mhi, int ch_id)
ch->reset_pending = false;
}
static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
static int mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
union mhi_dev_ring_element_type *el, void *ctx)
{
int rc = 0;
@ -1901,7 +1901,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
if (rc)
mhi_log(MHI_MSG_ERROR,
"Error with compl event\n");
return;
return rc;
}
goto send_start_completion_event;
}
@ -1921,7 +1921,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
if (rc)
mhi_log(MHI_MSG_ERROR,
"Error with compl event\n");
return;
return rc;
}
mhi->ring[mhi->ch_ring_start + ch_id].state =
@ -1943,7 +1943,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
if (rc)
mhi_log(MHI_MSG_ERROR,
"Error with compl event\n");
return;
return rc;
}
if (mhi->use_edma || mhi->use_ipa) {
@ -1959,7 +1959,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
mhi_log(MHI_MSG_ERROR,
"error starting event ring %d\n",
mhi->ch_ctx_cache[ch_id].err_indx);
return;
return rc;
}
}
mutex_lock(&mhi->ch[ch_id].ch_lock);
@ -2014,7 +2014,7 @@ send_start_completion_event:
rc = mhi_dev_flush_cmd_completion_events(mhi, &event);
if (rc) {
pr_err("stop event send failed\n");
return;
return rc;
}
} else {
/*
@ -2027,7 +2027,7 @@ send_start_completion_event:
ring = &mhi->ring[ch_id + mhi->ch_ring_start];
if (ring->state == RING_STATE_UINT) {
pr_err("Channel not opened for %d\n", ch_id);
return;
return -EINVAL;
}
ch = &mhi->ch[ch_id];
@ -2076,7 +2076,7 @@ send_start_completion_event:
rc = mhi_dev_flush_cmd_completion_events(mhi, &event);
if (rc) {
pr_err("stop event send failed\n");
return;
return rc;
}
} else {
@ -2087,7 +2087,7 @@ send_start_completion_event:
ring = &mhi->ring[ch_id + mhi->ch_ring_start];
if (ring->state == RING_STATE_UINT) {
pr_err("Channel not opened for %d\n", ch_id);
return;
return -EINVAL;
}
ch = &mhi->ch[ch_id];
mutex_lock(&ch->ch_lock);
@ -2099,7 +2099,8 @@ send_start_completion_event:
ch->reset_pending = true;
mutex_unlock(&ch->ring->event_lock);
mutex_unlock(&ch->ch_lock);
return;
rc = -EBUSY;
return rc;
}
mhi_dev_process_reset_cmd(mhi, ch_id);
mutex_unlock(&ch->ring->event_lock);
@ -2114,9 +2115,10 @@ send_start_completion_event:
pr_err("%s: Invalid command:%d\n", __func__, el->generic.type);
break;
}
return rc;
}
static void mhi_dev_process_tre_ring(struct mhi_dev *mhi,
static int mhi_dev_process_tre_ring(struct mhi_dev *mhi,
union mhi_dev_ring_element_type *el, void *ctx)
{
struct mhi_dev_ring *ring = (struct mhi_dev_ring *)ctx;
@ -2127,7 +2129,7 @@ static void mhi_dev_process_tre_ring(struct mhi_dev *mhi,
mhi_log(MHI_MSG_VERBOSE,
"invalid channel ring id (%d), should be < %lu\n",
ring->id, mhi->ch_ring_start);
return;
return -EINVAL;
}
ch = &mhi->ch[ring->id - mhi->ch_ring_start];
@ -2141,6 +2143,7 @@ static void mhi_dev_process_tre_ring(struct mhi_dev *mhi,
*/
if (ch->active_client && ch->active_client->event_trigger != NULL)
ch->active_client->event_trigger(&reason);
return 0;
}
static void mhi_dev_process_ring_pending(struct work_struct *work)
@ -2155,7 +2158,7 @@ static void mhi_dev_process_ring_pending(struct work_struct *work)
mutex_lock(&mhi_ctx->mhi_lock);
rc = mhi_dev_process_ring(&mhi->ring[mhi->cmd_ring_idx]);
if (rc) {
if (rc && rc != -EBUSY) {
mhi_log(MHI_MSG_ERROR, "error processing command ring\n");
goto exit;
}
@ -2181,6 +2184,7 @@ static void mhi_dev_process_ring_pending(struct work_struct *work)
}
mutex_lock(&ch->ch_lock);
ch->db_pending = false;
mutex_unlock(&ch->ch_lock);
if (ch->reset_pending) {
/*
@ -2191,9 +2195,13 @@ static void mhi_dev_process_ring_pending(struct work_struct *work)
ch_id = ch->ch_id;
mhi_log(MHI_MSG_VERBOSE,
"processing pending ch:%d reset\n", ch_id);
mutex_lock(&ch->ring->event_lock);
mhi_dev_process_reset_cmd(mhi, ch_id);
mutex_unlock(&ch->ring->event_lock);
rc = mhi_dev_process_ring(
&mhi->ring[mhi->cmd_ring_idx]);
if (rc) {
mhi_log(MHI_MSG_ERROR,
"error processing command ring\n");
goto exit;
}
}
rc = mhi_dev_mmio_enable_chdb_a7(mhi, ch->ch_id);
@ -2203,7 +2211,6 @@ static void mhi_dev_process_ring_pending(struct work_struct *work)
mutex_unlock(&ch->ch_lock);
goto exit;
}
mutex_unlock(&ch->ch_lock);
}
exit:

View file

@ -407,7 +407,7 @@ struct mhi_dev_ring {
/* ring_ctx_shadow -> tracking ring_ctx in the host */
union mhi_dev_ring_ctx *ring_ctx_shadow;
struct msi_buf_cb_data msi_buffer;
void (*ring_cb)(struct mhi_dev *dev,
int (*ring_cb)(struct mhi_dev *dev,
union mhi_dev_ring_element_type *el,
void *ctx);
};
@ -775,7 +775,7 @@ int mhi_dev_add_element(struct mhi_dev_ring *ring,
* @ring_cb: callback function.
*/
void mhi_ring_set_cb(struct mhi_dev_ring *ring,
void (*ring_cb)(struct mhi_dev *dev,
int (*ring_cb)(struct mhi_dev *dev,
union mhi_dev_ring_element_type *el, void *ctx));
/**

View file

@ -197,7 +197,7 @@ int mhi_dev_process_ring_element(struct mhi_dev_ring *ring, size_t offset)
el->tre.len, offset);
if (ring->ring_cb)
ring->ring_cb(ring->mhi_dev, el, (void *)ring);
return ring->ring_cb(ring->mhi_dev, el, (void *)ring);
else
mhi_log(MHI_MSG_ERROR, "No callback registered for ring %d\n",
ring->id);
@ -557,7 +557,7 @@ void mhi_ring_init(struct mhi_dev_ring *ring, enum mhi_dev_ring_type type,
EXPORT_SYMBOL(mhi_ring_init);
void mhi_ring_set_cb(struct mhi_dev_ring *ring,
void (*ring_cb)(struct mhi_dev *dev,
int (*ring_cb)(struct mhi_dev *dev,
union mhi_dev_ring_element_type *el, void *ctx))
{
if (WARN_ON(!ring || !ring_cb))