diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/diag/diagchar_core.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index eaed3b101095..4111e599877a 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -3029,6 +3029,16 @@ 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) { @@ -3041,9 +3051,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, int write_len = 0; struct diag_md_session_t *session_info = NULL; + mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) index = i; + mutex_unlock(&driver->diagchar_mutex); if (index == -1) { pr_err("diag: Client PID not found in table"); @@ -3053,7 +3065,7 @@ 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, driver->data_ready[index]); + wait_event_interruptible(driver->wait_q, (check_data_ready(index)) > 0); mutex_lock(&driver->diagchar_mutex); @@ -3194,11 +3206,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, } exit: - mutex_unlock(&driver->diagchar_mutex); if (driver->data_ready[index] & DCI_DATA_TYPE) { - mutex_lock(&driver->dci_mutex); - /* Copy the type of data being passed */ data_type = driver->data_ready[index] & DCI_DATA_TYPE; + mutex_unlock(&driver->diagchar_mutex); + /* Copy the type of data being passed */ + mutex_lock(&driver->dci_mutex); list_for_each_safe(start, temp, &driver->dci_client_list) { entry = list_entry(start, struct diag_dci_client_tbl, track); @@ -3230,6 +3242,7 @@ exit: mutex_unlock(&driver->dci_mutex); goto end; } + mutex_unlock(&driver->diagchar_mutex); end: /* * Flush any read that is currently pending on DCI data and |