summaryrefslogtreecommitdiff
path: root/drivers/char/diag
diff options
context:
space:
mode:
authorManoj Prabhu B <bmanoj@codeaurora.org>2016-08-26 11:56:13 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-08 23:56:37 -0700
commit9ce38e70a042b3eb9ca636e23f327618c8243024 (patch)
tree46739275af871505c44611886e553bc512615dd9 /drivers/char/diag
parent5964f2d700c413fa08cdd61f6756701d3642a7d8 (diff)
diag: Clear masks upon logging exit
This patch clears the peripheral masks upon the mdlog exit and USB disconnection. This enables to keep the data and cmd channel open for read. CRs-Fixed: 1057143 Change-Id: Ie6f19319b75f3bf389ddd5a8168fd3bcd3efbc8b Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
Diffstat (limited to 'drivers/char/diag')
-rw-r--r--drivers/char/diag/diag_masks.c9
-rw-r--r--drivers/char/diag/diag_usb.c6
-rw-r--r--drivers/char/diag/diagchar.h3
-rw-r--r--drivers/char/diag/diagchar_core.c35
-rw-r--r--drivers/char/diag/diagfwd.c17
5 files changed, 60 insertions, 10 deletions
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 7cb64e012f1f..a1721a3b80cc 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1780,6 +1780,15 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
if (!mask_info)
return -EIO;
+ mutex_lock(&driver->diag_maskclear_mutex);
+ if (driver->mask_clear) {
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag:%s: count = %zu\n", __func__, count);
+ mutex_unlock(&driver->diag_maskclear_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&driver->diag_maskclear_mutex);
+
mutex_lock(&mask_info->lock);
mask = (struct diag_msg_mask_t *)(mask_info->ptr);
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
diff --git a/drivers/char/diag/diag_usb.c b/drivers/char/diag/diag_usb.c
index eb715cc8501c..ca54b24ec604 100644
--- a/drivers/char/diag/diag_usb.c
+++ b/drivers/char/diag/diag_usb.c
@@ -215,6 +215,12 @@ static void usb_connect_work_fn(struct work_struct *work)
*/
static void usb_disconnect(struct diag_usb_info *ch)
{
+ if (!ch)
+ return;
+
+ if (!atomic_read(&ch->connected) && driver->usb_connected)
+ diag_clear_masks(NULL);
+
if (ch && ch->ops && ch->ops->close)
ch->ops->close(ch->ctxt, DIAG_USB_MODE);
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index dccaa6a0d9c4..2aef98f4fe04 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -467,6 +467,8 @@ struct diagchar_dev {
struct class *diagchar_class;
struct device *diag_dev;
int ref_count;
+ int mask_clear;
+ struct mutex diag_maskclear_mutex;
struct mutex diagchar_mutex;
struct mutex diag_file_mutex;
wait_queue_head_t wait_q;
@@ -625,6 +627,7 @@ void diag_cmd_remove_reg(struct diag_cmd_reg_entry_t *entry, uint8_t proc);
void diag_cmd_remove_reg_by_pid(int pid);
void diag_cmd_remove_reg_by_proc(int proc);
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
+void diag_clear_masks(struct diag_md_session_t *info);
void diag_record_stats(int type, int flag);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a39e4929d999..9ed43cdc3845 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -389,6 +389,27 @@ static uint32_t diag_translate_kernel_to_user_mask(uint32_t peripheral_mask)
return ret;
}
+void diag_clear_masks(struct diag_md_session_t *info)
+{
+ int ret;
+ char cmd_disable_log_mask[] = { 0x73, 0, 0, 0, 0, 0, 0, 0};
+ char cmd_disable_msg_mask[] = { 0x7D, 0x05, 0, 0, 0, 0, 0, 0};
+ char cmd_disable_event_mask[] = { 0x60, 0};
+
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag: %s: masks clear request upon %s\n", __func__,
+ ((info) ? "ODL exit" : "USB Disconnection"));
+
+ ret = diag_process_apps_masks(cmd_disable_log_mask,
+ sizeof(cmd_disable_log_mask), info);
+ ret = diag_process_apps_masks(cmd_disable_msg_mask,
+ sizeof(cmd_disable_msg_mask), info);
+ ret = diag_process_apps_masks(cmd_disable_event_mask,
+ sizeof(cmd_disable_event_mask), info);
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag:%s: masks cleared successfully\n", __func__);
+}
+
static void diag_close_logging_process(const int pid)
{
int i;
@@ -400,6 +421,12 @@ static void diag_close_logging_process(const int pid)
if (!session_info)
return;
+ diag_clear_masks(session_info);
+
+ mutex_lock(&driver->diag_maskclear_mutex);
+ driver->mask_clear = 1;
+ mutex_unlock(&driver->diag_maskclear_mutex);
+
session_peripheral_mask = session_info->peripheral_mask;
diag_md_session_close(session_info);
for (i = 0; i < NUM_MD_SESSIONS; i++)
@@ -475,9 +502,14 @@ static int diag_remove_client_entry(struct file *file)
}
static int diagchar_close(struct inode *inode, struct file *file)
{
+ int ret;
DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
current->comm);
- return diag_remove_client_entry(file);
+ ret = diag_remove_client_entry(file);
+ mutex_lock(&driver->diag_maskclear_mutex);
+ driver->mask_clear = 0;
+ mutex_unlock(&driver->diag_maskclear_mutex);
+ return ret;
}
void diag_record_stats(int type, int flag)
@@ -3358,6 +3390,7 @@ static int __init diagchar_init(void)
non_hdlc_data.len = 0;
mutex_init(&driver->hdlc_disable_mutex);
mutex_init(&driver->diagchar_mutex);
+ mutex_init(&driver->diag_maskclear_mutex);
mutex_init(&driver->diag_file_mutex);
mutex_init(&driver->delayed_rsp_mutex);
mutex_init(&apps_data_mutex);
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 8205e5b05d85..0111b02634c8 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1232,8 +1232,6 @@ static int diagfwd_mux_open(int id, int mode)
static int diagfwd_mux_close(int id, int mode)
{
- uint8_t i;
-
switch (mode) {
case DIAG_USB_MODE:
driver->usb_connected = 0;
@@ -1248,15 +1246,16 @@ static int diagfwd_mux_close(int id, int mode)
driver->md_session_mode == DIAG_MD_NONE) ||
(driver->md_session_mode == DIAG_MD_PERIPHERAL)) {
/*
- * In this case the channel must not be closed. This case
- * indicates that the USB is removed but there is a client
- * running in background with Memory Device mode
+ * This case indicates that the USB is removed
+ * but there is a client running in background
+ * with Memory Device mode.
*/
} else {
- for (i = 0; i < NUM_PERIPHERALS; i++) {
- diagfwd_close(i, TYPE_DATA);
- diagfwd_close(i, TYPE_CMD);
- }
+ /*
+ * With clearing of masks on ODL exit and
+ * USB disconnection, closing of the channel is
+ * not needed.This enables read and drop of stale packets.
+ */
/* Re enable HDLC encoding */
pr_debug("diag: In %s, re-enabling HDLC encoding\n",
__func__);