diag: Poll SMD control channel for data after USB connects
DIAG uses SMD control channels to transfer packet registration
information from slave processors. While USB is disconnected, under
some scenarios, the SMD data might be left unread. Hence, when USB
gets connected, a special effort has to be made to read any unread
data on SMD control channel. Also each time a registration information
is stored in diag table, the SMD channel needs to be polled once more.
Signed-off-by: Shalabh Jain <shalabhj@codeaurora.org>
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 34ffb6d..3dec655 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -959,6 +959,10 @@
queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
+ /* Poll SMD CNTL channels to check for data */
+ queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
+ queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_cntl_work));
+ queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_cntl_work));
/* Poll USB channel to check for data*/
queue_work(driver->diag_wq, &(driver->diag_read_work));
#ifdef CONFIG_DIAG_SDIO_PIPE
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 45226ba..41279d3 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -21,7 +21,7 @@
static void diag_smd_cntl_send_req(int proc_num)
{
- int data_len = 0, type = -1, count_bytes = 0, j, r;
+ int data_len = 0, type = -1, count_bytes = 0, j, r, flag = 0;
struct bindpkt_params_per_process *pkt_params =
kzalloc(sizeof(struct bindpkt_params_per_process), GFP_KERNEL);
struct diag_ctrl_msg *msg;
@@ -80,6 +80,7 @@
}
temp -= pkt_params->count;
pkt_params->params = temp;
+ flag = 1;
diagchar_ioctl(NULL, DIAG_IOCTL_COMMAND_REG,
(unsigned long)pkt_params);
kfree(temp);
@@ -88,6 +89,14 @@
}
}
kfree(pkt_params);
+ if (flag) {
+ /* Poll SMD CNTL channels to check for data */
+ queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_qdsp_cntl_work));
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_cntl_work));
+ }
}
void diag_read_smd_cntl_work_fn(struct work_struct *work)