Loading drivers/char/diag/diagchar.h +3 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,8 @@ struct diag_logging_mode_param_t { struct diag_md_session_t { int pid; int peripheral_mask; uint8_t hdlc_disabled; struct timer_list hdlc_reset_timer; struct diag_mask_info *msg_mask; struct diag_mask_info *log_mask; struct diag_mask_info *event_mask; Loading Loading @@ -550,6 +552,7 @@ struct diagchar_dev { struct workqueue_struct *diag_wq; struct work_struct diag_drain_work; struct work_struct update_user_clients; struct work_struct update_md_clients; struct workqueue_struct *diag_cntl_wq; uint8_t log_on_demand_support; uint8_t *apps_req_buf; Loading drivers/char/diag/diagchar_core.c +60 −13 Original line number Diff line number Diff line Loading @@ -226,12 +226,25 @@ void diag_update_user_client_work_fn(struct work_struct *work) diag_update_userspace_clients(HDLC_SUPPORT_TYPE); } static void diag_update_md_client_work_fn(struct work_struct *work) { diag_update_md_clients(HDLC_SUPPORT_TYPE); } void diag_drain_work_fn(struct work_struct *work) { timer_in_progress = 0; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; timer_in_progress = 0; mutex_lock(&apps_data_mutex); if (!driver->hdlc_disabled) session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!hdlc_disabled) diag_drain_apps_data(&hdlc_data); else diag_drain_apps_data(&non_hdlc_data); Loading Loading @@ -851,6 +864,8 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 }; struct diag_hdlc_dest_type enc = { NULL, NULL, 0 }; int bridge_index = proc - 1; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!buf) return -EINVAL; Loading @@ -875,8 +890,12 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; if (driver->hdlc_disabled) { session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) { payload = *(uint16_t *)(buf + 2); driver->hdlc_encode_buf_len = payload; /* Loading Loading @@ -1170,6 +1189,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) driver->md_session_map[i] = new_session; } driver->md_session_mode = DIAG_MD_NORMAL; setup_timer(&new_session->hdlc_reset_timer, diag_md_hdlc_reset_timer_func, new_session->pid); DIAG_LOG(DIAG_DEBUG_USERSPACE, "created session in normal mode\n"); mutex_unlock(&driver->md_session_lock); Loading Loading @@ -1213,7 +1235,6 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) "return value of msg copy. err %d\n", err); goto fail_peripheral; } for (i = 0; i < NUM_MD_SESSIONS; i++) { if ((MD_PERIPHERAL_MASK(i) & peripheral_mask) == 0) continue; Loading @@ -1226,6 +1247,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) new_session->peripheral_mask |= MD_PERIPHERAL_MASK(i); driver->md_session_map[i] = new_session; driver->md_session_mask |= MD_PERIPHERAL_MASK(i); setup_timer(&new_session->hdlc_reset_timer, diag_md_hdlc_reset_timer_func, new_session->pid); } driver->md_session_mode = DIAG_MD_PERIPHERAL; mutex_unlock(&driver->md_session_lock); Loading Loading @@ -1275,6 +1299,7 @@ static void diag_md_session_close(struct diag_md_session_t *session_info) diag_event_mask_free(session_info->event_mask); kfree(session_info->event_mask); session_info->event_mask = NULL; del_timer(&session_info->hdlc_reset_timer); } for (i = 0; i < NUM_MD_SESSIONS && !found; i++) { Loading Loading @@ -1771,15 +1796,21 @@ static int diag_ioctl_dci_support(unsigned long ioarg) static int diag_ioctl_hdlc_toggle(unsigned long ioarg) { uint8_t hdlc_support; struct diag_md_session_t *session_info = NULL; session_info = diag_md_session_get_pid(current->tgid); if (copy_from_user(&hdlc_support, (void __user *)ioarg, sizeof(uint8_t))) return -EFAULT; mutex_lock(&driver->hdlc_disable_mutex); if (session_info) { mutex_lock(&driver->md_session_lock); session_info->hdlc_disabled = hdlc_support; mutex_unlock(&driver->md_session_lock); } else driver->hdlc_disabled = hdlc_support; mutex_unlock(&driver->hdlc_disable_mutex); diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); return 0; } Loading Loading @@ -2465,6 +2496,7 @@ static int diag_user_process_userspace_data(const char __user *buf, int len) int remote_proc = 0; int token_offset = 0; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; if (!buf || len <= 0 || len > USER_SPACE_DATA) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", Loading Loading @@ -2518,7 +2550,11 @@ static int diag_user_process_userspace_data(const char __user *buf, int len) __func__, current->tgid); return -EINVAL; } if (!driver->hdlc_disabled) if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!hdlc_disabled) diag_process_hdlc_pkt((void *) (driver->user_space_data_buf), len, session_info); Loading Loading @@ -2548,6 +2584,8 @@ static int diag_user_process_apps_data(const char __user *buf, int len, int stm_size = 0; const int mempool = POOL_TYPE_COPY; unsigned char *user_space_data = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; if (!buf || len <= 0 || len > DIAG_MAX_RSP_SIZE) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", Loading Loading @@ -2600,13 +2638,17 @@ static int diag_user_process_apps_data(const char __user *buf, int len, mutex_lock(&apps_data_mutex); mutex_lock(&driver->hdlc_disable_mutex); if (driver->hdlc_disabled) { session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) ret = diag_process_apps_data_non_hdlc(user_space_data, len, pkt_type); } else { else ret = diag_process_apps_data_hdlc(user_space_data, len, pkt_type); } mutex_unlock(&driver->hdlc_disable_mutex); mutex_unlock(&apps_data_mutex); Loading Loading @@ -2676,7 +2718,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE; driver->data_ready[index] ^= HDLC_SUPPORT_TYPE; COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); COPY_USER_SPACE_OR_EXIT(buf+4, driver->hdlc_disabled, session_info = diag_md_session_get_pid(current->tgid); if (session_info) COPY_USER_SPACE_OR_EXIT(buf+4, session_info->hdlc_disabled, sizeof(uint8_t)); goto exit; } Loading Loading @@ -3247,6 +3292,8 @@ static int __init diagchar_init(void) INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn); INIT_WORK(&(driver->update_user_clients), diag_update_user_client_work_fn); INIT_WORK(&(driver->update_md_clients), diag_update_md_client_work_fn); diag_ws_init(); diag_stats_init(); diag_debug_init(); Loading drivers/char/diag/diagfwd.c +71 −12 Original line number Diff line number Diff line Loading @@ -382,7 +382,16 @@ static void encode_rsp_and_send(unsigned char *buf, int len) void diag_send_rsp(unsigned char *buf, int len) { if (driver->hdlc_disabled) struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) pack_rsp_and_send(buf, len); else encode_rsp_and_send(buf, len); Loading Loading @@ -444,6 +453,24 @@ void diag_update_userspace_clients(unsigned int type) mutex_unlock(&driver->diagchar_mutex); } void diag_update_md_clients(unsigned int type) { int i, j; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (driver->md_session_map[i] != NULL) for (j = 0; j < driver->num_clients; j++) { if (driver->client_map[j].pid != 0 && driver->client_map[j].pid == driver->md_session_map[i]->pid) driver->data_ready[j] |= type; break; } } wake_up_interruptible(&driver->wait_q); mutex_unlock(&driver->diagchar_mutex); } void diag_update_sleeping_process(int process_id, int data_type) { int i; Loading Loading @@ -889,6 +916,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, if (temp_entry) { reg_item = container_of(temp_entry, struct diag_cmd_reg_t, entry); if (info) { if (MD_PERIPHERAL_MASK(reg_item->proc) & info->peripheral_mask) write_len = diag_send_data(reg_item, buf, len); } else write_len = diag_send_data(reg_item, buf, len); mutex_unlock(&driver->cmd_reg_mutex); return write_len; Loading Loading @@ -1048,8 +1080,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, */ pr_debug("diag: In %s, disabling HDLC encoding\n", __func__); if (info) info->hdlc_disabled = 1; else driver->hdlc_disabled = 1; diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); mutex_unlock(&driver->hdlc_disable_mutex); return 0; } Loading Loading @@ -1212,6 +1247,7 @@ static int diagfwd_mux_close(int id, int mode) pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); mutex_lock(&driver->hdlc_disable_mutex); if (driver->md_session_mode == DIAG_MD_NONE) driver->hdlc_disabled = 0; mutex_unlock(&driver->hdlc_disable_mutex); queue_work(driver->diag_wq, Loading @@ -1224,10 +1260,14 @@ static int diagfwd_mux_close(int id, int mode) static uint8_t hdlc_reset; static void hdlc_reset_timer_start(void) static void hdlc_reset_timer_start(struct diag_md_session_t *info) { if (!hdlc_timer_in_progress) { hdlc_timer_in_progress = 1; if (info) mod_timer(&info->hdlc_reset_timer, jiffies + msecs_to_jiffies(200)); else mod_timer(&driver->hdlc_reset_timer, jiffies + msecs_to_jiffies(200)); } Loading @@ -1235,7 +1275,6 @@ static void hdlc_reset_timer_start(void) static void hdlc_reset_timer_func(unsigned long data) { pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { Loading @@ -1246,6 +1285,22 @@ static void hdlc_reset_timer_func(unsigned long data) hdlc_timer_in_progress = 0; } void diag_md_hdlc_reset_timer_func(unsigned long pid) { struct diag_md_session_t *session_info = NULL; pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { session_info = diag_md_session_get_pid(pid); if (session_info) session_info->hdlc_disabled = 0; queue_work(driver->diag_wq, &(driver->update_md_clients)); } hdlc_timer_in_progress = 0; } static void diag_hdlc_start_recovery(unsigned char *buf, int len, struct diag_md_session_t *info) { Loading @@ -1255,7 +1310,7 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, struct diag_pkt_frame_t *actual_pkt = NULL; hdlc_reset = 1; hdlc_reset_timer_start(); hdlc_reset_timer_start(info); actual_pkt = (struct diag_pkt_frame_t *)buf; for (i = 0; i < len; i++) { Loading @@ -1274,9 +1329,13 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, pr_err("diag: In %s, re-enabling HDLC encoding\n", __func__); mutex_lock(&driver->hdlc_disable_mutex); if (info) info->hdlc_disabled = 0; else driver->hdlc_disabled = 0; mutex_unlock(&driver->hdlc_disable_mutex); diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); return; } } Loading drivers/char/diag/diagfwd.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,6 @@ int diag_process_apps_pkt(unsigned char *buf, int len, void diag_send_error_rsp(unsigned char *buf, int len); void diag_update_pkt_buffer(unsigned char *buf, uint32_t len, int type); int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf); void diag_md_hdlc_reset_timer_func(unsigned long pid); void diag_update_md_clients(unsigned int type); #endif drivers/char/diag/diagfwd_peripheral.c +11 −4 Original line number Diff line number Diff line Loading @@ -219,7 +219,8 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, int write_len = 0; unsigned char *write_buf = NULL; struct diagfwd_buf_t *temp_buf = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!fwd_info || !buf || len <= 0) { diag_ws_release(); return; Loading @@ -239,6 +240,12 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&fwd_info->data_mutex); session_info = diag_md_session_get_peripheral(fwd_info->peripheral); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!driver->feature[fwd_info->peripheral].encode_hdlc) { if (fwd_info->buf_1 && fwd_info->buf_1->data == buf) { temp_buf = fwd_info->buf_1; Loading @@ -253,7 +260,7 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, goto end; } write_len = len; } else if (driver->hdlc_disabled) { } else if (hdlc_disabled) { /* The data is raw and and on APPS side HDLC is disabled */ if (fwd_info->buf_1 && fwd_info->buf_1->data_raw == buf) { temp_buf = fwd_info->buf_1; Loading Loading
drivers/char/diag/diagchar.h +3 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,8 @@ struct diag_logging_mode_param_t { struct diag_md_session_t { int pid; int peripheral_mask; uint8_t hdlc_disabled; struct timer_list hdlc_reset_timer; struct diag_mask_info *msg_mask; struct diag_mask_info *log_mask; struct diag_mask_info *event_mask; Loading Loading @@ -550,6 +552,7 @@ struct diagchar_dev { struct workqueue_struct *diag_wq; struct work_struct diag_drain_work; struct work_struct update_user_clients; struct work_struct update_md_clients; struct workqueue_struct *diag_cntl_wq; uint8_t log_on_demand_support; uint8_t *apps_req_buf; Loading
drivers/char/diag/diagchar_core.c +60 −13 Original line number Diff line number Diff line Loading @@ -226,12 +226,25 @@ void diag_update_user_client_work_fn(struct work_struct *work) diag_update_userspace_clients(HDLC_SUPPORT_TYPE); } static void diag_update_md_client_work_fn(struct work_struct *work) { diag_update_md_clients(HDLC_SUPPORT_TYPE); } void diag_drain_work_fn(struct work_struct *work) { timer_in_progress = 0; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; timer_in_progress = 0; mutex_lock(&apps_data_mutex); if (!driver->hdlc_disabled) session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!hdlc_disabled) diag_drain_apps_data(&hdlc_data); else diag_drain_apps_data(&non_hdlc_data); Loading Loading @@ -851,6 +864,8 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 }; struct diag_hdlc_dest_type enc = { NULL, NULL, 0 }; int bridge_index = proc - 1; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!buf) return -EINVAL; Loading @@ -875,8 +890,12 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; if (driver->hdlc_disabled) { session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) { payload = *(uint16_t *)(buf + 2); driver->hdlc_encode_buf_len = payload; /* Loading Loading @@ -1170,6 +1189,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) driver->md_session_map[i] = new_session; } driver->md_session_mode = DIAG_MD_NORMAL; setup_timer(&new_session->hdlc_reset_timer, diag_md_hdlc_reset_timer_func, new_session->pid); DIAG_LOG(DIAG_DEBUG_USERSPACE, "created session in normal mode\n"); mutex_unlock(&driver->md_session_lock); Loading Loading @@ -1213,7 +1235,6 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) "return value of msg copy. err %d\n", err); goto fail_peripheral; } for (i = 0; i < NUM_MD_SESSIONS; i++) { if ((MD_PERIPHERAL_MASK(i) & peripheral_mask) == 0) continue; Loading @@ -1226,6 +1247,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) new_session->peripheral_mask |= MD_PERIPHERAL_MASK(i); driver->md_session_map[i] = new_session; driver->md_session_mask |= MD_PERIPHERAL_MASK(i); setup_timer(&new_session->hdlc_reset_timer, diag_md_hdlc_reset_timer_func, new_session->pid); } driver->md_session_mode = DIAG_MD_PERIPHERAL; mutex_unlock(&driver->md_session_lock); Loading Loading @@ -1275,6 +1299,7 @@ static void diag_md_session_close(struct diag_md_session_t *session_info) diag_event_mask_free(session_info->event_mask); kfree(session_info->event_mask); session_info->event_mask = NULL; del_timer(&session_info->hdlc_reset_timer); } for (i = 0; i < NUM_MD_SESSIONS && !found; i++) { Loading Loading @@ -1771,15 +1796,21 @@ static int diag_ioctl_dci_support(unsigned long ioarg) static int diag_ioctl_hdlc_toggle(unsigned long ioarg) { uint8_t hdlc_support; struct diag_md_session_t *session_info = NULL; session_info = diag_md_session_get_pid(current->tgid); if (copy_from_user(&hdlc_support, (void __user *)ioarg, sizeof(uint8_t))) return -EFAULT; mutex_lock(&driver->hdlc_disable_mutex); if (session_info) { mutex_lock(&driver->md_session_lock); session_info->hdlc_disabled = hdlc_support; mutex_unlock(&driver->md_session_lock); } else driver->hdlc_disabled = hdlc_support; mutex_unlock(&driver->hdlc_disable_mutex); diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); return 0; } Loading Loading @@ -2465,6 +2496,7 @@ static int diag_user_process_userspace_data(const char __user *buf, int len) int remote_proc = 0; int token_offset = 0; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; if (!buf || len <= 0 || len > USER_SPACE_DATA) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", Loading Loading @@ -2518,7 +2550,11 @@ static int diag_user_process_userspace_data(const char __user *buf, int len) __func__, current->tgid); return -EINVAL; } if (!driver->hdlc_disabled) if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!hdlc_disabled) diag_process_hdlc_pkt((void *) (driver->user_space_data_buf), len, session_info); Loading Loading @@ -2548,6 +2584,8 @@ static int diag_user_process_apps_data(const char __user *buf, int len, int stm_size = 0; const int mempool = POOL_TYPE_COPY; unsigned char *user_space_data = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; if (!buf || len <= 0 || len > DIAG_MAX_RSP_SIZE) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", Loading Loading @@ -2600,13 +2638,17 @@ static int diag_user_process_apps_data(const char __user *buf, int len, mutex_lock(&apps_data_mutex); mutex_lock(&driver->hdlc_disable_mutex); if (driver->hdlc_disabled) { session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) ret = diag_process_apps_data_non_hdlc(user_space_data, len, pkt_type); } else { else ret = diag_process_apps_data_hdlc(user_space_data, len, pkt_type); } mutex_unlock(&driver->hdlc_disable_mutex); mutex_unlock(&apps_data_mutex); Loading Loading @@ -2676,7 +2718,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE; driver->data_ready[index] ^= HDLC_SUPPORT_TYPE; COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); COPY_USER_SPACE_OR_EXIT(buf+4, driver->hdlc_disabled, session_info = diag_md_session_get_pid(current->tgid); if (session_info) COPY_USER_SPACE_OR_EXIT(buf+4, session_info->hdlc_disabled, sizeof(uint8_t)); goto exit; } Loading Loading @@ -3247,6 +3292,8 @@ static int __init diagchar_init(void) INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn); INIT_WORK(&(driver->update_user_clients), diag_update_user_client_work_fn); INIT_WORK(&(driver->update_md_clients), diag_update_md_client_work_fn); diag_ws_init(); diag_stats_init(); diag_debug_init(); Loading
drivers/char/diag/diagfwd.c +71 −12 Original line number Diff line number Diff line Loading @@ -382,7 +382,16 @@ static void encode_rsp_and_send(unsigned char *buf, int len) void diag_send_rsp(unsigned char *buf, int len) { if (driver->hdlc_disabled) struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled; session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) pack_rsp_and_send(buf, len); else encode_rsp_and_send(buf, len); Loading Loading @@ -444,6 +453,24 @@ void diag_update_userspace_clients(unsigned int type) mutex_unlock(&driver->diagchar_mutex); } void diag_update_md_clients(unsigned int type) { int i, j; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (driver->md_session_map[i] != NULL) for (j = 0; j < driver->num_clients; j++) { if (driver->client_map[j].pid != 0 && driver->client_map[j].pid == driver->md_session_map[i]->pid) driver->data_ready[j] |= type; break; } } wake_up_interruptible(&driver->wait_q); mutex_unlock(&driver->diagchar_mutex); } void diag_update_sleeping_process(int process_id, int data_type) { int i; Loading Loading @@ -889,6 +916,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, if (temp_entry) { reg_item = container_of(temp_entry, struct diag_cmd_reg_t, entry); if (info) { if (MD_PERIPHERAL_MASK(reg_item->proc) & info->peripheral_mask) write_len = diag_send_data(reg_item, buf, len); } else write_len = diag_send_data(reg_item, buf, len); mutex_unlock(&driver->cmd_reg_mutex); return write_len; Loading Loading @@ -1048,8 +1080,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, */ pr_debug("diag: In %s, disabling HDLC encoding\n", __func__); if (info) info->hdlc_disabled = 1; else driver->hdlc_disabled = 1; diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); mutex_unlock(&driver->hdlc_disable_mutex); return 0; } Loading Loading @@ -1212,6 +1247,7 @@ static int diagfwd_mux_close(int id, int mode) pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); mutex_lock(&driver->hdlc_disable_mutex); if (driver->md_session_mode == DIAG_MD_NONE) driver->hdlc_disabled = 0; mutex_unlock(&driver->hdlc_disable_mutex); queue_work(driver->diag_wq, Loading @@ -1224,10 +1260,14 @@ static int diagfwd_mux_close(int id, int mode) static uint8_t hdlc_reset; static void hdlc_reset_timer_start(void) static void hdlc_reset_timer_start(struct diag_md_session_t *info) { if (!hdlc_timer_in_progress) { hdlc_timer_in_progress = 1; if (info) mod_timer(&info->hdlc_reset_timer, jiffies + msecs_to_jiffies(200)); else mod_timer(&driver->hdlc_reset_timer, jiffies + msecs_to_jiffies(200)); } Loading @@ -1235,7 +1275,6 @@ static void hdlc_reset_timer_start(void) static void hdlc_reset_timer_func(unsigned long data) { pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { Loading @@ -1246,6 +1285,22 @@ static void hdlc_reset_timer_func(unsigned long data) hdlc_timer_in_progress = 0; } void diag_md_hdlc_reset_timer_func(unsigned long pid) { struct diag_md_session_t *session_info = NULL; pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { session_info = diag_md_session_get_pid(pid); if (session_info) session_info->hdlc_disabled = 0; queue_work(driver->diag_wq, &(driver->update_md_clients)); } hdlc_timer_in_progress = 0; } static void diag_hdlc_start_recovery(unsigned char *buf, int len, struct diag_md_session_t *info) { Loading @@ -1255,7 +1310,7 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, struct diag_pkt_frame_t *actual_pkt = NULL; hdlc_reset = 1; hdlc_reset_timer_start(); hdlc_reset_timer_start(info); actual_pkt = (struct diag_pkt_frame_t *)buf; for (i = 0; i < len; i++) { Loading @@ -1274,9 +1329,13 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, pr_err("diag: In %s, re-enabling HDLC encoding\n", __func__); mutex_lock(&driver->hdlc_disable_mutex); if (info) info->hdlc_disabled = 0; else driver->hdlc_disabled = 0; mutex_unlock(&driver->hdlc_disable_mutex); diag_update_userspace_clients(HDLC_SUPPORT_TYPE); diag_update_md_clients(HDLC_SUPPORT_TYPE); return; } } Loading
drivers/char/diag/diagfwd.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,6 @@ int diag_process_apps_pkt(unsigned char *buf, int len, void diag_send_error_rsp(unsigned char *buf, int len); void diag_update_pkt_buffer(unsigned char *buf, uint32_t len, int type); int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf); void diag_md_hdlc_reset_timer_func(unsigned long pid); void diag_update_md_clients(unsigned int type); #endif
drivers/char/diag/diagfwd_peripheral.c +11 −4 Original line number Diff line number Diff line Loading @@ -219,7 +219,8 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, int write_len = 0; unsigned char *write_buf = NULL; struct diagfwd_buf_t *temp_buf = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!fwd_info || !buf || len <= 0) { diag_ws_release(); return; Loading @@ -239,6 +240,12 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&fwd_info->data_mutex); session_info = diag_md_session_get_peripheral(fwd_info->peripheral); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; if (!driver->feature[fwd_info->peripheral].encode_hdlc) { if (fwd_info->buf_1 && fwd_info->buf_1->data == buf) { temp_buf = fwd_info->buf_1; Loading @@ -253,7 +260,7 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, goto end; } write_len = len; } else if (driver->hdlc_disabled) { } else if (hdlc_disabled) { /* The data is raw and and on APPS side HDLC is disabled */ if (fwd_info->buf_1 && fwd_info->buf_1->data_raw == buf) { temp_buf = fwd_info->buf_1; Loading