summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/diag/diag_debugfs.c7
-rw-r--r--drivers/char/diag/diag_memorydevice.c1
-rw-r--r--drivers/char/diag/diagchar.h5
-rw-r--r--drivers/char/diag/diagchar_core.c35
-rw-r--r--drivers/char/diag/diagfwd.c10
5 files changed, 41 insertions, 17 deletions
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index c963e4658c07..5e455878ac3e 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -52,7 +52,7 @@ static int diag_dbgfs_bridgeinfo_index;
static int diag_dbgfs_finished;
static int diag_dbgfs_dci_data_index;
static int diag_dbgfs_dci_finished;
-
+static struct mutex diag_dci_dbgfs_mutex;
static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
@@ -159,6 +159,7 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
buf_size = ksize(buf);
bytes_remaining = buf_size;
+ mutex_lock(&diag_dci_dbgfs_mutex);
if (diag_dbgfs_dci_data_index == 0) {
bytes_written =
scnprintf(buf, buf_size,
@@ -214,8 +215,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
}
temp_data++;
}
-
diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1;
+ mutex_unlock(&diag_dci_dbgfs_mutex);
bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf,
bytes_in_buf);
kfree(buf);
@@ -1186,6 +1187,7 @@ int diag_debugfs_init(void)
pr_warn("diag: could not allocate memory for dci debug info\n");
mutex_init(&dci_stat_mutex);
+ mutex_init(&diag_dci_dbgfs_mutex);
return 0;
err:
kfree(dci_traffic);
@@ -1202,6 +1204,7 @@ void diag_debugfs_cleanup(void)
kfree(dci_traffic);
mutex_destroy(&dci_stat_mutex);
+ mutex_destroy(&diag_dci_dbgfs_mutex);
}
#else
int diag_debugfs_init(void) { return 0; }
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index 986aeed169f5..072c55ca3c4e 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -202,6 +202,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
found = 1;
driver->data_ready[i] |= USER_SPACE_DATA_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
pr_debug("diag: wake up logging process\n");
wake_up_interruptible(&driver->wait_q);
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index d81a39e2c637..80f004b8435e 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -26,6 +26,8 @@
#include <asm/atomic.h>
#include "diagfwd_bridge.h"
+#define THRESHOLD_CLIENT_LIMIT 50
+
/* Size of the USB buffers used for read and write*/
#define USB_MAX_OUT_BUF 4096
#define APPS_BUF_SIZE 4096
@@ -34,7 +36,7 @@
#define DIAG_MAX_REQ_SIZE (16 * 1024)
#define DIAG_MAX_RSP_SIZE (16 * 1024)
-#define APF_DIAG_PADDING 256
+#define APF_DIAG_PADDING 0
/*
* In the worst case, the HDLC buffer can be atmost twice the size of the
* original packet. Add 3 bytes for 16 bit CRC (2 bytes) and a delimiter
@@ -508,6 +510,7 @@ struct diagchar_dev {
wait_queue_head_t wait_q;
struct diag_client_map *client_map;
int *data_ready;
+ atomic_t data_ready_notif[THRESHOLD_CLIENT_LIMIT];
int num_clients;
int polling_reg_flag;
int use_device_tree;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 4111e599877a..ae0182ae77db 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -139,7 +139,6 @@ module_param(poolsize_qsc_usb, uint, 0);
/* This is the max number of user-space clients supported at initialization*/
static unsigned int max_clients = 15;
-static unsigned int threshold_client_limit = 50;
module_param(max_clients, uint, 0);
/* Timer variables */
@@ -328,7 +327,7 @@ static int diagchar_open(struct inode *inode, struct file *file)
if (i < driver->num_clients) {
diag_add_client(i, file);
} else {
- if (i < threshold_client_limit) {
+ if (i < THRESHOLD_CLIENT_LIMIT) {
driver->num_clients++;
temp = krealloc(driver->client_map
, (driver->num_clients) * sizeof(struct
@@ -358,11 +357,17 @@ static int diagchar_open(struct inode *inode, struct file *file)
}
}
driver->data_ready[i] = 0x0;
+ atomic_set(&driver->data_ready_notif[i], 0);
driver->data_ready[i] |= MSG_MASKS_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
driver->data_ready[i] |= EVENT_MASKS_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
driver->data_ready[i] |= LOG_MASKS_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
driver->data_ready[i] |= DCI_LOG_MASKS_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
driver->data_ready[i] |= DCI_EVENT_MASKS_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
if (driver->ref_count == 0)
diag_mempool_init();
@@ -1866,6 +1871,7 @@ static int diag_ioctl_lsm_deinit(void)
}
driver->data_ready[i] |= DEINIT_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
mutex_unlock(&driver->diagchar_mutex);
wake_up_interruptible(&driver->wait_q);
@@ -3029,16 +3035,6 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
return 0;
}
-static int check_data_ready(int index)
-{
- int data_type = 0;
-
- mutex_lock(&driver->diagchar_mutex);
- data_type = driver->data_ready[index];
- mutex_unlock(&driver->diagchar_mutex);
- return data_type;
-}
-
static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
@@ -3065,7 +3061,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
pr_err("diag: bad address from user side\n");
return -EFAULT;
}
- wait_event_interruptible(driver->wait_q, (check_data_ready(index)) > 0);
+ wait_event_interruptible(driver->wait_q,
+ atomic_read(&driver->data_ready_notif[index]) > 0);
mutex_lock(&driver->diagchar_mutex);
@@ -3076,6 +3073,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
/*Copy the type of data being passed*/
data_type = driver->data_ready[index] & USER_SPACE_DATA_TYPE;
driver->data_ready[index] ^= USER_SPACE_DATA_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
/* place holder for number of data field */
ret += sizeof(int);
@@ -3089,11 +3087,13 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
/* In case, the thread wakes up and the logging mode is
not memory device any more, the condition needs to be cleared */
driver->data_ready[index] ^= USER_SPACE_DATA_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
}
if (driver->data_ready[index] & HDLC_SUPPORT_TYPE) {
data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE;
driver->data_ready[index] ^= HDLC_SUPPORT_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
mutex_lock(&driver->md_session_lock);
session_info = diag_md_session_get_pid(current->tgid);
@@ -3110,6 +3110,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
data_type = driver->data_ready[index] & DEINIT_TYPE;
COPY_USER_SPACE_OR_EXIT(buf, data_type, 4);
driver->data_ready[index] ^= DEINIT_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
mutex_unlock(&driver->diagchar_mutex);
diag_remove_client_entry(file);
return ret;
@@ -3125,6 +3126,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
if (write_len > 0)
ret += write_len;
driver->data_ready[index] ^= MSG_MASKS_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
goto exit;
}
@@ -3144,6 +3146,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
event_mask.mask_len);
}
driver->data_ready[index] ^= EVENT_MASKS_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
goto exit;
}
@@ -3157,6 +3160,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
if (write_len > 0)
ret += write_len;
driver->data_ready[index] ^= LOG_MASKS_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
goto exit;
}
@@ -3168,6 +3172,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
*(driver->apps_req_buf),
driver->apps_req_buf_len);
driver->data_ready[index] ^= PKT_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
driver->in_busy_pktdata = 0;
goto exit;
}
@@ -3179,6 +3184,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
COPY_USER_SPACE_OR_EXIT(buf+4, *(driver->dci_pkt_buf),
driver->dci_pkt_length);
driver->data_ready[index] ^= DCI_PKT_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
driver->in_busy_dcipktdata = 0;
goto exit;
}
@@ -3191,6 +3197,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
COPY_USER_SPACE_OR_EXIT(buf + 8, (dci_ops_tbl[DCI_LOCAL_PROC].
event_mask_composite), DCI_EVENT_MASK_SIZE);
driver->data_ready[index] ^= DCI_EVENT_MASKS_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
goto exit;
}
@@ -3202,6 +3209,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
COPY_USER_SPACE_OR_EXIT(buf+8, (dci_ops_tbl[DCI_LOCAL_PROC].
log_mask_composite), DCI_LOG_MASK_SIZE);
driver->data_ready[index] ^= DCI_LOG_MASKS_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
goto exit;
}
@@ -3233,6 +3241,7 @@ exit:
exit_stat = diag_copy_dci(buf, count, entry, &ret);
mutex_lock(&driver->diagchar_mutex);
driver->data_ready[index] ^= DCI_DATA_TYPE;
+ atomic_dec(&driver->data_ready_notif[index]);
mutex_unlock(&driver->diagchar_mutex);
if (exit_stat == 1) {
mutex_unlock(&driver->dci_mutex);
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index ef08f939c36e..40412ba87897 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -226,6 +226,7 @@ void chk_logging_wakeup(void)
* situation.
*/
driver->data_ready[i] |= USER_SPACE_DATA_TYPE;
+ atomic_inc(&driver->data_ready_notif[i]);
pr_debug("diag: Force wakeup of logging process\n");
wake_up_interruptible(&driver->wait_q);
break;
@@ -480,8 +481,10 @@ void diag_update_userspace_clients(unsigned int type)
mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
- if (driver->client_map[i].pid != 0)
+ if (driver->client_map[i].pid != 0) {
driver->data_ready[i] |= type;
+ atomic_inc(&driver->data_ready_notif[i]);
+ }
wake_up_interruptible(&driver->wait_q);
mutex_unlock(&driver->diagchar_mutex);
}
@@ -498,6 +501,8 @@ void diag_update_md_clients(unsigned int type)
driver->client_map[j].pid ==
driver->md_session_map[i]->pid) {
driver->data_ready[j] |= type;
+ atomic_inc(
+ &driver->data_ready_notif[j]);
break;
}
}
@@ -513,6 +518,7 @@ void diag_update_sleeping_process(int process_id, int data_type)
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == process_id) {
driver->data_ready[i] |= data_type;
+ atomic_inc(&driver->data_ready_notif[i]);
break;
}
wake_up_interruptible(&driver->wait_q);
@@ -1703,6 +1709,8 @@ int diagfwd_init(void)
, GFP_KERNEL)) == NULL)
goto err;
kmemleak_not_leak(driver->data_ready);
+ for (i = 0; i < THRESHOLD_CLIENT_LIMIT; i++)
+ atomic_set(&driver->data_ready_notif[i], 0);
if (driver->apps_req_buf == NULL) {
driver->apps_req_buf = kzalloc(DIAG_MAX_REQ_SIZE, GFP_KERNEL);
if (!driver->apps_req_buf)