Merge "msm: mhi: fix latent issues in MHI drivers"

This commit is contained in:
Linux Build Service Account 2017-02-11 01:25:13 -08:00 committed by Gerrit - the friendly Code Review server
commit aee0c0c2ad
5 changed files with 22 additions and 15 deletions

View file

@ -915,6 +915,7 @@ static void rmnet_mhi_cb(struct mhi_cb_info *cb_info)
} else { } else {
rmnet_log(MSG_CRITICAL, rmnet_log(MSG_CRITICAL,
"Invalid data in MHI callback, quitting\n"); "Invalid data in MHI callback, quitting\n");
return;
} }
switch (cb_info->cb_reason) { switch (cb_info->cb_reason) {

View file

@ -19,7 +19,7 @@ static int add_element(struct mhi_ring *ring, void **rp,
uintptr_t d_wp = 0, d_rp = 0, ring_size = 0; uintptr_t d_wp = 0, d_rp = 0, ring_size = 0;
int r; int r;
if (0 == ring->el_size || NULL == ring if (NULL == ring || 0 == ring->el_size
|| NULL == ring->base || 0 == ring->len) { || NULL == ring->base || 0 == ring->len) {
mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n"); mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n");
return -EINVAL; return -EINVAL;
@ -77,7 +77,7 @@ int delete_element(struct mhi_ring *ring, void **rp,
uintptr_t d_wp = 0, d_rp = 0, ring_size = 0; uintptr_t d_wp = 0, d_rp = 0, ring_size = 0;
int r; int r;
if (0 == ring->el_size || NULL == ring || if (NULL == ring || 0 == ring->el_size ||
NULL == ring->base || 0 == ring->len) NULL == ring->base || 0 == ring->len)
return -EINVAL; return -EINVAL;
@ -143,7 +143,7 @@ int get_nr_enclosed_el(struct mhi_ring *ring, void *rp,
uintptr_t ring_size = 0; uintptr_t ring_size = 0;
int r = 0; int r = 0;
if (0 == ring->el_size || NULL == ring || if (NULL == ring || 0 == ring->el_size ||
NULL == ring->base || 0 == ring->len) { NULL == ring->base || 0 == ring->len) {
mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n"); mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n");
return -EINVAL; return -EINVAL;

View file

@ -179,7 +179,7 @@ static int set_mhi_base_state(struct mhi_pcie_dev_info *mhi_pcie_dev)
void mhi_link_state_cb(struct msm_pcie_notify *notify) void mhi_link_state_cb(struct msm_pcie_notify *notify)
{ {
int ret_val = 0; int ret_val = 0;
struct mhi_pcie_dev_info *mhi_pcie_dev = notify->data; struct mhi_pcie_dev_info *mhi_pcie_dev;
struct mhi_device_ctxt *mhi_dev_ctxt = NULL; struct mhi_device_ctxt *mhi_dev_ctxt = NULL;
int r = 0; int r = 0;
@ -188,6 +188,8 @@ void mhi_link_state_cb(struct msm_pcie_notify *notify)
"Incomplete handle received\n"); "Incomplete handle received\n");
return; return;
} }
mhi_pcie_dev = notify->data;
mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt; mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt;
switch (notify->event) { switch (notify->event) {
case MSM_PCIE_EVENT_LINKDOWN: case MSM_PCIE_EVENT_LINKDOWN:

View file

@ -53,16 +53,16 @@ static ssize_t mhi_dbgfs_chan_read(struct file *fp, char __user *buf,
*offp = (u32)(*offp) % MHI_MAX_CHANNELS; *offp = (u32)(*offp) % MHI_MAX_CHANNELS;
while (!valid_chan) { while (!valid_chan) {
client_handle = mhi_dev_ctxt->client_handle_list[*offp];
if (*offp == (MHI_MAX_CHANNELS - 1)) if (*offp == (MHI_MAX_CHANNELS - 1))
msleep(1000); msleep(1000);
if (!VALID_CHAN_NR(*offp) || if (!VALID_CHAN_NR(*offp) ||
!cc_list[*offp].mhi_trb_ring_base_addr || !cc_list[*offp].mhi_trb_ring_base_addr ||
!client_handle) { !mhi_dev_ctxt->client_handle_list[*offp]) {
*offp += 1; *offp += 1;
*offp = (u32)(*offp) % MHI_MAX_CHANNELS; *offp = (u32)(*offp) % MHI_MAX_CHANNELS;
continue; continue;
} }
client_handle = mhi_dev_ctxt->client_handle_list[*offp];
valid_chan = 1; valid_chan = 1;
} }

View file

@ -623,17 +623,20 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
struct file *file_handle) struct file *file_handle)
{ {
struct uci_client *uci_handle = file_handle->private_data; struct uci_client *uci_handle = file_handle->private_data;
struct mhi_uci_ctxt_t *uci_ctxt = uci_handle->uci_ctxt; struct mhi_uci_ctxt_t *uci_ctxt;
u32 nr_in_bufs = 0; u32 nr_in_bufs = 0;
int in_chan = 0; int in_chan = 0;
int i = 0; int i = 0;
u32 buf_size = 0; u32 buf_size = 0;
if (uci_handle == NULL)
return -EINVAL;
uci_ctxt = uci_handle->uci_ctxt;
in_chan = iminor(mhi_inode) + 1; in_chan = iminor(mhi_inode) + 1;
nr_in_bufs = uci_ctxt->chan_attrib[in_chan].nr_trbs; nr_in_bufs = uci_ctxt->chan_attrib[in_chan].nr_trbs;
buf_size = uci_ctxt->chan_attrib[in_chan].max_packet_size; buf_size = uci_ctxt->chan_attrib[in_chan].max_packet_size;
if (uci_handle == NULL)
return -EINVAL;
if (atomic_sub_return(1, &uci_handle->ref_count) == 0) { if (atomic_sub_return(1, &uci_handle->ref_count) == 0) {
uci_log(UCI_DBG_ERROR, uci_log(UCI_DBG_ERROR,
"Last client left, closing channel 0x%x\n", "Last client left, closing channel 0x%x\n",
@ -1021,14 +1024,15 @@ static void uci_xfer_cb(struct mhi_cb_info *cb_info)
u32 client_index; u32 client_index;
struct mhi_result *result; struct mhi_result *result;
if (!cb_info) if (!cb_info || !cb_info->result) {
uci_log(UCI_DBG_CRITICAL, "Bad CB info from MHI.\n"); uci_log(UCI_DBG_CRITICAL, "Bad CB info from MHI.\n");
if (cb_info->result) { return;
}
chan_nr = (uintptr_t)cb_info->result->user_data; chan_nr = (uintptr_t)cb_info->result->user_data;
client_index = CHAN_TO_CLIENT(chan_nr); client_index = CHAN_TO_CLIENT(chan_nr);
uci_handle = uci_handle = &uci_ctxt.client_handles[client_index];
&uci_ctxt.client_handles[client_index];
}
switch (cb_info->cb_reason) { switch (cb_info->cb_reason) {
case MHI_CB_MHI_ENABLED: case MHI_CB_MHI_ENABLED:
atomic_set(&uci_handle->mhi_disabled, 0); atomic_set(&uci_handle->mhi_disabled, 0);