Loading drivers/char/diag/diag_dci.c +18 −3 Original line number Diff line number Diff line Loading @@ -343,6 +343,7 @@ void diag_dci_wakeup_clients() struct list_head *start, *temp; struct diag_dci_client_tbl *entry = NULL; 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); Loading @@ -358,6 +359,7 @@ void diag_dci_wakeup_clients() DCI_DATA_TYPE); } } mutex_unlock(&driver->dci_mutex); } void dci_data_drain_work_fn(struct work_struct *work) Loading @@ -368,6 +370,7 @@ void dci_data_drain_work_fn(struct work_struct *work) struct diag_dci_buf_peripheral_t *proc_buf = NULL; struct diag_dci_buffer_t *buf_temp = NULL; 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); for (i = 0; i < entry->num_buffers; i++) { Loading Loading @@ -397,6 +400,7 @@ void dci_data_drain_work_fn(struct work_struct *work) DCI_DATA_TYPE); } } mutex_unlock(&driver->dci_mutex); dci_timer_in_progress = 0; } Loading Loading @@ -562,6 +566,8 @@ start: buf += header_len + dci_pkt_len; /* advance to next DCI pkt */ } end: if (err) return; /* wake up all sleeping DCI clients which have some data */ diag_dci_wakeup_clients(); dci_check_drain_timer(); Loading Loading @@ -623,6 +629,8 @@ void diag_dci_process_peripheral_data(struct diagfwd_info *p_info, void *buf, buf += 5 + dci_pkt_len; /* advance to next DCI pkt */ } if (err) return; /* wake up all sleeping DCI clients which have some data */ diag_dci_wakeup_clients(); dci_check_drain_timer(); Loading Loading @@ -970,9 +978,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, return; } mutex_lock(&driver->dci_mutex); req_entry = diag_dci_get_request_entry(tag); if (!req_entry) { pr_err("diag: No matching client for DCI data\n"); pr_err_ratelimited("diag: No matching client for DCI data\n"); mutex_unlock(&driver->dci_mutex); return; } Loading @@ -980,18 +990,17 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, if (!entry) { pr_err("diag: In %s, couldn't find client entry, id:%d\n", __func__, req_entry->client_id); mutex_unlock(&driver->dci_mutex); return; } save_req_uid = req_entry->uid; /* Remove the headers and send only the response to this function */ mutex_lock(&driver->dci_mutex); delete_flag = diag_dci_remove_req_entry(temp, rsp_len, req_entry); if (delete_flag < 0) { mutex_unlock(&driver->dci_mutex); return; } mutex_unlock(&driver->dci_mutex); mutex_lock(&entry->buffers[data_source].buf_mutex); rsp_buf = entry->buffers[data_source].buf_cmd; Loading @@ -1011,6 +1020,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, pr_err("diag: DCI realloc failed\n"); mutex_unlock(&rsp_buf->data_mutex); mutex_unlock(&entry->buffers[data_source].buf_mutex); mutex_unlock(&driver->dci_mutex); return; } else { rsp_buf->data = temp_buf; Loading Loading @@ -1039,6 +1049,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, */ dci_add_buffer_to_list(entry, rsp_buf); mutex_unlock(&entry->buffers[data_source].buf_mutex); mutex_unlock(&driver->dci_mutex); } static void copy_dci_event(unsigned char *buf, int len, Loading Loading @@ -1174,6 +1185,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token) the event data */ total_event_len = 2 + 10 + payload_len_field + payload_len; /* parse through event mask tbl of each client and check mask */ 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); Loading @@ -1185,6 +1197,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token) entry, data_source); } } mutex_unlock(&driver->dci_mutex); } } Loading Loading @@ -1276,6 +1289,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token) } /* parse through log mask table of each client and check mask */ 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); if (entry->client_info.token != token) Loading @@ -1287,6 +1301,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token) copy_dci_log(buf, len, entry, data_source); } } mutex_unlock(&driver->dci_mutex); } void diag_dci_channel_open_work(struct work_struct *work) Loading drivers/char/diag/diagchar_core.c +23 −9 Original line number Diff line number Diff line Loading @@ -2393,7 +2393,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, goto exit; } 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; list_for_each_safe(start, temp, &driver->dci_client_list) { Loading @@ -2403,20 +2406,31 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, continue; if (!entry->in_service) continue; COPY_USER_SPACE_OR_EXIT(buf + ret, data_type, sizeof(int)); COPY_USER_SPACE_OR_EXIT(buf + ret, entry->client_info.token, sizeof(int)); if (copy_to_user(buf + ret, &data_type, sizeof(int))) { mutex_unlock(&driver->dci_mutex); goto end; } ret += sizeof(int); if (copy_to_user(buf + ret, &entry->client_info.token, sizeof(int))) { mutex_unlock(&driver->dci_mutex); goto end; } ret += sizeof(int); copy_dci_data = 1; exit_stat = diag_copy_dci(buf, count, entry, &ret); mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= DCI_DATA_TYPE; if (exit_stat == 1) goto exit; mutex_unlock(&driver->diagchar_mutex); if (exit_stat == 1) { mutex_unlock(&driver->dci_mutex); goto end; } goto exit; } exit: mutex_unlock(&driver->diagchar_mutex); mutex_unlock(&driver->dci_mutex); goto end; } end: /* * Flush any read that is currently pending on DCI data and * command channnels. This will ensure that the next read is not Loading Loading
drivers/char/diag/diag_dci.c +18 −3 Original line number Diff line number Diff line Loading @@ -343,6 +343,7 @@ void diag_dci_wakeup_clients() struct list_head *start, *temp; struct diag_dci_client_tbl *entry = NULL; 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); Loading @@ -358,6 +359,7 @@ void diag_dci_wakeup_clients() DCI_DATA_TYPE); } } mutex_unlock(&driver->dci_mutex); } void dci_data_drain_work_fn(struct work_struct *work) Loading @@ -368,6 +370,7 @@ void dci_data_drain_work_fn(struct work_struct *work) struct diag_dci_buf_peripheral_t *proc_buf = NULL; struct diag_dci_buffer_t *buf_temp = NULL; 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); for (i = 0; i < entry->num_buffers; i++) { Loading Loading @@ -397,6 +400,7 @@ void dci_data_drain_work_fn(struct work_struct *work) DCI_DATA_TYPE); } } mutex_unlock(&driver->dci_mutex); dci_timer_in_progress = 0; } Loading Loading @@ -562,6 +566,8 @@ start: buf += header_len + dci_pkt_len; /* advance to next DCI pkt */ } end: if (err) return; /* wake up all sleeping DCI clients which have some data */ diag_dci_wakeup_clients(); dci_check_drain_timer(); Loading Loading @@ -623,6 +629,8 @@ void diag_dci_process_peripheral_data(struct diagfwd_info *p_info, void *buf, buf += 5 + dci_pkt_len; /* advance to next DCI pkt */ } if (err) return; /* wake up all sleeping DCI clients which have some data */ diag_dci_wakeup_clients(); dci_check_drain_timer(); Loading Loading @@ -970,9 +978,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, return; } mutex_lock(&driver->dci_mutex); req_entry = diag_dci_get_request_entry(tag); if (!req_entry) { pr_err("diag: No matching client for DCI data\n"); pr_err_ratelimited("diag: No matching client for DCI data\n"); mutex_unlock(&driver->dci_mutex); return; } Loading @@ -980,18 +990,17 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, if (!entry) { pr_err("diag: In %s, couldn't find client entry, id:%d\n", __func__, req_entry->client_id); mutex_unlock(&driver->dci_mutex); return; } save_req_uid = req_entry->uid; /* Remove the headers and send only the response to this function */ mutex_lock(&driver->dci_mutex); delete_flag = diag_dci_remove_req_entry(temp, rsp_len, req_entry); if (delete_flag < 0) { mutex_unlock(&driver->dci_mutex); return; } mutex_unlock(&driver->dci_mutex); mutex_lock(&entry->buffers[data_source].buf_mutex); rsp_buf = entry->buffers[data_source].buf_cmd; Loading @@ -1011,6 +1020,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, pr_err("diag: DCI realloc failed\n"); mutex_unlock(&rsp_buf->data_mutex); mutex_unlock(&entry->buffers[data_source].buf_mutex); mutex_unlock(&driver->dci_mutex); return; } else { rsp_buf->data = temp_buf; Loading Loading @@ -1039,6 +1049,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, */ dci_add_buffer_to_list(entry, rsp_buf); mutex_unlock(&entry->buffers[data_source].buf_mutex); mutex_unlock(&driver->dci_mutex); } static void copy_dci_event(unsigned char *buf, int len, Loading Loading @@ -1174,6 +1185,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token) the event data */ total_event_len = 2 + 10 + payload_len_field + payload_len; /* parse through event mask tbl of each client and check mask */ 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); Loading @@ -1185,6 +1197,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token) entry, data_source); } } mutex_unlock(&driver->dci_mutex); } } Loading Loading @@ -1276,6 +1289,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token) } /* parse through log mask table of each client and check mask */ 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); if (entry->client_info.token != token) Loading @@ -1287,6 +1301,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token) copy_dci_log(buf, len, entry, data_source); } } mutex_unlock(&driver->dci_mutex); } void diag_dci_channel_open_work(struct work_struct *work) Loading
drivers/char/diag/diagchar_core.c +23 −9 Original line number Diff line number Diff line Loading @@ -2393,7 +2393,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, goto exit; } 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; list_for_each_safe(start, temp, &driver->dci_client_list) { Loading @@ -2403,20 +2406,31 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, continue; if (!entry->in_service) continue; COPY_USER_SPACE_OR_EXIT(buf + ret, data_type, sizeof(int)); COPY_USER_SPACE_OR_EXIT(buf + ret, entry->client_info.token, sizeof(int)); if (copy_to_user(buf + ret, &data_type, sizeof(int))) { mutex_unlock(&driver->dci_mutex); goto end; } ret += sizeof(int); if (copy_to_user(buf + ret, &entry->client_info.token, sizeof(int))) { mutex_unlock(&driver->dci_mutex); goto end; } ret += sizeof(int); copy_dci_data = 1; exit_stat = diag_copy_dci(buf, count, entry, &ret); mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= DCI_DATA_TYPE; if (exit_stat == 1) goto exit; mutex_unlock(&driver->diagchar_mutex); if (exit_stat == 1) { mutex_unlock(&driver->dci_mutex); goto end; } goto exit; } exit: mutex_unlock(&driver->diagchar_mutex); mutex_unlock(&driver->dci_mutex); goto end; } end: /* * Flush any read that is currently pending on DCI data and * command channnels. This will ensure that the next read is not Loading