diff options
Diffstat (limited to 'drivers/soc/qcom/spcom.c')
| -rw-r--r-- | drivers/soc/qcom/spcom.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 07610877f140..cab758f695dc 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -898,12 +898,12 @@ static int spcom_rx(struct spcom_channel *ch, goto exit_err; } +copy_buf: if (!ch->glink_rx_buf) { pr_err("invalid glink_rx_buf.\n"); goto exit_err; } -copy_buf: /* Copy from glink buffer to spcom buffer */ size = min_t(int, ch->actual_rx_size, size); memcpy(buf, ch->glink_rx_buf, size); @@ -1723,12 +1723,16 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch, pr_debug("ion handle ok.\n"); + /* ION buf lock doesn't involve any rx/tx data to SP. */ + mutex_lock(&ch->lock); + /* Check if this ION buffer is already locked */ for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) { if (ch->ion_handle_table[i] == ion_handle) { pr_err("fd [%d] ion buf is already locked.\n", fd); /* decrement back the ref count */ ion_free(spcom_dev->ion_client, ion_handle); + mutex_unlock(&ch->lock); return -EINVAL; } } @@ -1740,11 +1744,16 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch, ch->ion_fd_table[i] = fd; pr_debug("ch [%s] locked ion buf #%d, fd [%d].\n", ch->name, i, fd); + mutex_unlock(&ch->lock); return 0; } } - pr_err("fd [%d] ion buf not found.\n", fd); + pr_err("no free entry to store ion handle of fd [%d].\n", fd); + /* decrement back the ref count */ + ion_free(spcom_dev->ion_client, ion_handle); + + mutex_unlock(&ch->lock); return -EFAULT; } @@ -1824,8 +1833,13 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch, return -EINVAL; } + /* ION buf unlock doesn't involve any rx/tx data to SP. */ + mutex_lock(&ch->lock); + ret = spcom_unlock_ion_buf(ch, fd); + mutex_unlock(&ch->lock); + return ret; } @@ -2241,7 +2255,7 @@ static ssize_t spcom_device_write(struct file *filp, } /** - * spcom_device_read() - handle channel file write() from user space. + * spcom_device_read() - handle channel file read() from user space. * * @filp: file pointer * @@ -2267,6 +2281,16 @@ static ssize_t spcom_device_read(struct file *filp, char __user *user_buff, ch = filp->private_data; + if (ch == NULL) { + pr_err("invalid ch pointer, file [%s].\n", name); + return -EINVAL; + } + + if (!spcom_is_channel_open(ch)) { + pr_err("ch is not open, file [%s].\n", name); + return -EINVAL; + } + buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; @@ -2354,6 +2378,10 @@ static unsigned int spcom_device_poll(struct file *filp, done = (spcom_dev->link_state == GLINK_LINK_STATE_UP); break; case SPCOM_POLL_CH_CONNECT: + if (ch == NULL) { + pr_err("invalid ch pointer, file [%s].\n", name); + return -EINVAL; + } pr_debug("ch [%s] SPCOM_POLL_CH_CONNECT.\n", name); if (wait) { reinit_completion(&ch->connect); |
