summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/spcom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/qcom/spcom.c')
-rw-r--r--drivers/soc/qcom/spcom.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c
index c2af34926b37..d1f300e6afb7 100644
--- a/drivers/soc/qcom/spcom.c
+++ b/drivers/soc/qcom/spcom.c
@@ -121,7 +121,7 @@
/*
* After both sides get CONNECTED,
- * there is a race between once side queueing rx buffer and the other side
+ * there is a race between once side queuing rx buffer and the other side
* trying to call glink_tx() , this race is only on the 1st tx.
* do tx retry with some delay to allow the other side to queue rx buffer.
*/
@@ -138,7 +138,7 @@
/*
* ACK timeout from remote side for TX data.
- * Normally, it takes few msec for SPSS to responde with ACK for TX data.
+ * Normally, it takes few msec for SPSS to respond with ACK for TX data.
* However, due to SPSS HW issue, the SPSS might disable interrupts
* for a very long time.
*/
@@ -364,7 +364,7 @@ static void spcom_link_state_notif_cb(struct glink_link_state_cb_info *cb_info,
const char *ch_name = "sp_kernel";
if (!cb_info) {
- pr_err("invalid NULL cb_info.\n");
+ pr_err("invalid NULL cb_info param\n");
return;
}
@@ -718,12 +718,11 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec)
/* only one client/server may use the channel */
if (ch->ref_count) {
- pr_err("channel [%s] already in use.\n", name);
- goto exit_err;
+ pr_err("channel [%s] is BUSY, already in use by pid [%d].\n",
+ name, ch->pid);
+ mutex_unlock(&ch->lock);
+ return -EBUSY;
}
- ch->ref_count++;
- ch->pid = current_pid();
- ch->txn_id = INITIAL_TXN_ID;
pr_debug("ch [%s] opened by PID [%d], count [%d]\n",
name, ch->pid, ch->ref_count);
@@ -748,7 +747,12 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec)
} else {
pr_debug("glink_open [%s] ok.\n", name);
}
+
+ /* init channel context after successful open */
ch->glink_handle = handle;
+ ch->ref_count++;
+ ch->pid = current_pid();
+ ch->txn_id = INITIAL_TXN_ID;
pr_debug("Wait for connection on channel [%s] timeout_msec [%d].\n",
name, timeout_msec);
@@ -1480,6 +1484,7 @@ static int spcom_handle_create_channel_command(void *cmd_buf, int cmd_size)
int ret = 0;
struct spcom_user_create_channel_command *cmd = cmd_buf;
const char *ch_name;
+ const size_t maxlen = sizeof(cmd->ch_name);
if (cmd_size != sizeof(*cmd)) {
pr_err("cmd_size [%d] , expected [%d].\n",
@@ -1488,6 +1493,10 @@ static int spcom_handle_create_channel_command(void *cmd_buf, int cmd_size)
}
ch_name = cmd->ch_name;
+ if (strnlen(cmd->ch_name, maxlen) == maxlen) {
+ pr_err("channel name is not NULL terminated\n");
+ return -EINVAL;
+ }
pr_debug("ch_name [%s].\n", ch_name);
@@ -1626,7 +1635,7 @@ static int modify_ion_addr(void *buf,
/* Get ION handle from fd */
handle = ion_import_dma_buf(spcom_dev->ion_client, fd);
- if (handle == NULL) {
+ if (IS_ERR_OR_NULL(handle)) {
pr_err("fail to get ion handle.\n");
return -EINVAL;
}
@@ -1787,7 +1796,7 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch,
/* Get ION handle from fd - this increments the ref count */
ion_handle = ion_import_dma_buf(spcom_dev->ion_client, fd);
- if (ion_handle == NULL) {
+ if (IS_ERR_OR_NULL(ion_handle)) {
pr_err("fail to get ion handle.\n");
return -EINVAL;
}
@@ -1865,6 +1874,8 @@ static int spcom_unlock_ion_buf(struct spcom_channel *ch, int fd)
} else {
/* unlock specific ION buf */
for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) {
+ if (ch->ion_handle_table[i] == NULL)
+ continue;
if (ch->ion_fd_table[i] == fd) {
pr_debug("unlocked ion buf #%d fd [%d].\n",
i, ch->ion_fd_table[i]);
@@ -1932,9 +1943,9 @@ static int spcom_handle_write(struct spcom_channel *ch,
int swap_id;
char cmd_name[5] = {0}; /* debug only */
- /* opcode field is the minimum length of cmd */
- if (buf_size < sizeof(cmd->cmd_id)) {
- pr_err("Invalid argument user buffer size %d.\n", buf_size);
+ /* Minimal command should have command-id and argument */
+ if (buf_size < sizeof(struct spcom_user_command)) {
+ pr_err("Command buffer size [%d] too small\n", buf_size);
return -EINVAL;
}
@@ -2024,7 +2035,7 @@ static int spcom_handle_read_req_resp(struct spcom_channel *ch,
/* Check param validity */
if (size > SPCOM_MAX_RESPONSE_SIZE) {
- pr_err("ch [%s] inavlid size [%d].\n",
+ pr_err("ch [%s] invalid size [%d].\n",
ch->name, size);
return -EINVAL;
}
@@ -2152,6 +2163,10 @@ static int spcom_device_open(struct inode *inode, struct file *filp)
struct spcom_channel *ch;
const char *name = file_to_filename(filp);
+ /* silent error message until spss link is up */
+ if (!spcom_is_sp_subsystem_link_up())
+ return -ENODEV;
+
pr_debug("Open file [%s].\n", name);
if (strcmp(name, DEVICE_NAME) == 0) {