Loading drivers/char/diag/diagchar.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -580,6 +580,7 @@ struct diagchar_dev { /* buffer for updating mask to peripherals */ unsigned char *buf_feature_mask_update; uint8_t hdlc_disabled; uint8_t p_hdlc_disabled[NUM_MD_SESSIONS]; struct mutex hdlc_disable_mutex; struct mutex hdlc_recovery_mutex; struct timer_list hdlc_reset_timer; Loading @@ -604,6 +605,7 @@ struct diagchar_dev { struct work_struct diag_drain_work; struct work_struct update_user_clients; struct work_struct update_md_clients; struct work_struct diag_hdlc_reset_work; struct workqueue_struct *diag_cntl_wq; uint8_t log_on_demand_support; uint8_t *apps_req_buf; Loading Loading @@ -683,5 +685,6 @@ void diag_record_stats(int type, int flag); struct diag_md_session_t *diag_md_session_get_pid(int pid); struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral); int diag_md_session_match_pid_peripheral(int pid, uint8_t peripheral); #endif drivers/char/diag/diagchar_core.c +74 −25 Original line number Diff line number Diff line Loading @@ -252,18 +252,13 @@ static void diag_update_md_client_work_fn(struct work_struct *work) void diag_drain_work_fn(struct work_struct *work) { struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; timer_in_progress = 0; mutex_lock(&apps_data_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->hdlc_disable_mutex); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; mutex_unlock(&driver->hdlc_disable_mutex); if (!hdlc_disabled) diag_drain_apps_data(&hdlc_data); else Loading Loading @@ -1029,7 +1024,6 @@ 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) Loading @@ -1055,13 +1049,9 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->hdlc_disable_mutex); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; mutex_unlock(&driver->hdlc_disable_mutex); if (hdlc_disabled) { if (len < 4) { pr_err("diag: In %s, invalid len: %d of non_hdlc pkt", Loading Loading @@ -1483,6 +1473,43 @@ struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral) return driver->md_session_map[peripheral]; } /* * diag_md_session_match_pid_peripheral * * 1. Pass valid PID and get all the peripherals in logging session * for that PID * 2. Pass valid Peipheral and get the pid logging for that peripheral * */ int diag_md_session_match_pid_peripheral(int pid, uint8_t peripheral) { int i, flag = 0; if (pid <= 0 || peripheral >= NUM_MD_SESSIONS) return -EINVAL; if (!peripheral) { for (i = 0; i < NUM_MD_SESSIONS; i++) { if (driver->md_session_map[i] && driver->md_session_map[i]->pid == pid) { peripheral |= 1 << i; flag = 1; } } if (flag) return peripheral; } if (!pid) { if (driver->md_session_map[peripheral]) return driver->md_session_map[peripheral]->pid; } return -EINVAL; } static int diag_md_peripheral_switch(int pid, int peripheral_mask, int req_mode) { int i, bit = 0; Loading Loading @@ -1637,6 +1664,13 @@ static int diag_md_session_check(int curr_mode, int req_mode, } err = diag_md_session_create(DIAG_MD_PERIPHERAL, param->peripheral_mask, DIAG_LOCAL_PROC); mutex_lock(&driver->hdlc_disable_mutex); for (i = 0; i < NUM_MD_SESSIONS; i++) { if ((param->peripheral_mask > 0) && (param->peripheral_mask & (1 << i))) driver->p_hdlc_disabled[i] = 0; } mutex_unlock(&driver->hdlc_disable_mutex); } *change_mode = 1; return err; Loading Loading @@ -2085,11 +2119,14 @@ static int diag_ioctl_dci_support(unsigned long ioarg) static int diag_ioctl_hdlc_toggle(unsigned long ioarg) { uint8_t hdlc_support; uint8_t hdlc_support, i; int peripheral = -EINVAL; struct diag_md_session_t *session_info = NULL; if (copy_from_user(&hdlc_support, (void __user *)ioarg, sizeof(uint8_t))) return -EFAULT; mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); Loading @@ -2097,6 +2134,25 @@ static int diag_ioctl_hdlc_toggle(unsigned long ioarg) session_info->hdlc_disabled = hdlc_support; else driver->hdlc_disabled = hdlc_support; peripheral = diag_md_session_match_pid_peripheral(current->tgid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && session_info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = session_info->hdlc_disabled; else if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); diag_update_md_clients(HDLC_SUPPORT_TYPE); Loading Loading @@ -2970,7 +3026,6 @@ 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) { Loading Loading @@ -3024,13 +3079,7 @@ static int diag_user_process_apps_data(const char __user *buf, int len, mutex_lock(&apps_data_mutex); mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; if (hdlc_disabled) ret = diag_process_apps_data_non_hdlc(user_space_data, len, pkt_type); Loading drivers/char/diag/diagfwd.c +134 −12 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ #define STM_RSP_STATUS_INDEX 8 #define STM_RSP_NUM_BYTES 9 struct diag_md_hdlc_reset_work { int pid; struct work_struct work; }; static int timestamp_switch; module_param(timestamp_switch, int, 0644); Loading Loading @@ -436,6 +441,7 @@ static void diag_send_rsp(unsigned char *buf, int len, int pid) { struct diag_md_session_t *session_info = NULL, *info = NULL; uint8_t hdlc_disabled; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); session_info = (info) ? info : Loading @@ -445,6 +451,7 @@ static void diag_send_rsp(unsigned char *buf, int len, int pid) else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); if (hdlc_disabled) pack_rsp_and_send(buf, len, pid); else Loading Loading @@ -948,7 +955,7 @@ void diag_send_error_rsp(unsigned char *buf, int len, int diag_process_apps_pkt(unsigned char *buf, int len, int pid) { int i, p_mask = 0; int mask_ret; int mask_ret, peripheral = -EINVAL; int write_len = 0; unsigned char *temp = NULL; struct diag_cmd_reg_entry_t entry; Loading Loading @@ -1175,6 +1182,22 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) info->hdlc_disabled = 1; else driver->hdlc_disabled = 1; peripheral = diag_md_session_match_pid_peripheral(pid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = info->hdlc_disabled; else if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); diag_update_md_clients(HDLC_SUPPORT_TYPE); mutex_unlock(&driver->hdlc_disable_mutex); Loading Loading @@ -1350,8 +1373,17 @@ 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) if (driver->md_session_mode == DIAG_MD_NONE) { driver->hdlc_disabled = 0; /* * HDLC encoding is re-enabled when * there is logical/physical disconnection of diag * to USB. */ for (i = 0; i < NUM_MD_SESSIONS; i++) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } mutex_unlock(&driver->hdlc_disable_mutex); queue_work(driver->diag_wq, &(driver->update_user_clients)); Loading @@ -1366,6 +1398,7 @@ static uint8_t hdlc_reset; static void hdlc_reset_timer_start(int pid) { struct diag_md_session_t *info = NULL; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); if (!hdlc_timer_in_progress) { Loading @@ -1380,30 +1413,99 @@ static void hdlc_reset_timer_start(int pid) mutex_unlock(&driver->md_session_lock); } /* * diag_timer_work_fn * Queued in workqueue to protect md_session_info structure * * Update hdlc_disabled for each peripheral * which are not in any md_session_info. * */ static void diag_timer_work_fn(struct work_struct *work) { int i = 0; struct diag_md_session_t *session_info = NULL; mutex_lock(&driver->hdlc_disable_mutex); driver->hdlc_disabled = 0; mutex_lock(&driver->md_session_lock); for (i = 0; i < NUM_MD_SESSIONS; i++) { session_info = diag_md_session_get_peripheral(i); if (!session_info) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); } /* * diag_md_timer_work_fn * Queued in workqueue to protect md_session_info structure * * Update hdlc_disabled for each peripheral * which are in any md_session_info * */ static void diag_md_timer_work_fn(struct work_struct *work) { int peripheral = -EINVAL, i = 0; struct diag_md_session_t *session_info = NULL; struct diag_md_hdlc_reset_work *hdlc_work = container_of(work, struct diag_md_hdlc_reset_work, work); if (!hdlc_work) return; mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(hdlc_work->pid); if (session_info) session_info->hdlc_disabled = 0; peripheral = diag_md_session_match_pid_peripheral(hdlc_work->pid, 0); if (peripheral > 0 && session_info) { for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = session_info->hdlc_disabled; } } kfree(hdlc_work); mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); } static void hdlc_reset_timer_func(unsigned long data) { pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { driver->hdlc_disabled = 0; queue_work(driver->diag_wq, &(driver->update_user_clients)); queue_work(driver->diag_wq, &(driver->diag_hdlc_reset_work)); queue_work(driver->diag_wq, &(driver->update_user_clients)); } hdlc_timer_in_progress = 0; } void diag_md_hdlc_reset_timer_func(unsigned long pid) { struct diag_md_session_t *session_info = NULL; struct diag_md_hdlc_reset_work *hdlc_reset_work = NULL; pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); hdlc_reset_work = kmalloc(sizeof(*hdlc_reset_work), GFP_ATOMIC); if (!hdlc_reset_work) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: Could not allocate hdlc_reset_work\n"); hdlc_timer_in_progress = 0; return; } 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_reset_work->pid = pid; INIT_WORK(&hdlc_reset_work->work, diag_md_timer_work_fn); queue_work(driver->diag_wq, &(hdlc_reset_work->work)); queue_work(driver->diag_wq, &(driver->update_md_clients)); } hdlc_timer_in_progress = 0; } Loading @@ -1411,7 +1513,7 @@ void diag_md_hdlc_reset_timer_func(unsigned long pid) static void diag_hdlc_start_recovery(unsigned char *buf, int len, int pid) { int i; int i, peripheral = -EINVAL; static uint32_t bad_byte_counter; unsigned char *start_ptr = NULL; struct diag_pkt_frame_t *actual_pkt = NULL; Loading Loading @@ -1443,6 +1545,24 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, info->hdlc_disabled = 0; else driver->hdlc_disabled = 0; peripheral = diag_md_session_match_pid_peripheral(pid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = info->hdlc_disabled; else if ( !diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); diag_update_md_clients(HDLC_SUPPORT_TYPE); Loading Loading @@ -1700,6 +1820,8 @@ int diagfwd_init(void) INIT_LIST_HEAD(&driver->cmd_reg_list); driver->cmd_reg_count = 0; mutex_init(&driver->cmd_reg_mutex); INIT_WORK(&(driver->diag_hdlc_reset_work), diag_timer_work_fn); for (i = 0; i < NUM_PERIPHERALS; i++) { driver->feature[i].separate_cmd_rsp = 0; Loading drivers/char/diag/diagfwd_peripheral.c +6 −16 Original line number Diff line number Diff line Loading @@ -284,7 +284,6 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info, int err = 0; int write_len = 0, peripheral = 0; unsigned char *write_buf = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!fwd_info || !buf || len <= 0) { Loading Loading @@ -316,13 +315,9 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info, diag_ws_release(); return; } mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(peripheral); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[peripheral]; if (hdlc_disabled) { /* The data is raw and and on APPS side HDLC is disabled */ if (!buf) { Loading Loading @@ -615,7 +610,6 @@ 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) { Loading @@ -637,13 +631,9 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&fwd_info->data_mutex); mutex_lock(&driver->md_session_lock); 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; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[fwd_info->peripheral]; 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 Loading
drivers/char/diag/diagchar.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -580,6 +580,7 @@ struct diagchar_dev { /* buffer for updating mask to peripherals */ unsigned char *buf_feature_mask_update; uint8_t hdlc_disabled; uint8_t p_hdlc_disabled[NUM_MD_SESSIONS]; struct mutex hdlc_disable_mutex; struct mutex hdlc_recovery_mutex; struct timer_list hdlc_reset_timer; Loading @@ -604,6 +605,7 @@ struct diagchar_dev { struct work_struct diag_drain_work; struct work_struct update_user_clients; struct work_struct update_md_clients; struct work_struct diag_hdlc_reset_work; struct workqueue_struct *diag_cntl_wq; uint8_t log_on_demand_support; uint8_t *apps_req_buf; Loading Loading @@ -683,5 +685,6 @@ void diag_record_stats(int type, int flag); struct diag_md_session_t *diag_md_session_get_pid(int pid); struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral); int diag_md_session_match_pid_peripheral(int pid, uint8_t peripheral); #endif
drivers/char/diag/diagchar_core.c +74 −25 Original line number Diff line number Diff line Loading @@ -252,18 +252,13 @@ static void diag_update_md_client_work_fn(struct work_struct *work) void diag_drain_work_fn(struct work_struct *work) { struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; timer_in_progress = 0; mutex_lock(&apps_data_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->hdlc_disable_mutex); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; mutex_unlock(&driver->hdlc_disable_mutex); if (!hdlc_disabled) diag_drain_apps_data(&hdlc_data); else Loading Loading @@ -1029,7 +1024,6 @@ 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) Loading @@ -1055,13 +1049,9 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->hdlc_disable_mutex); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; mutex_unlock(&driver->hdlc_disable_mutex); if (hdlc_disabled) { if (len < 4) { pr_err("diag: In %s, invalid len: %d of non_hdlc pkt", Loading Loading @@ -1483,6 +1473,43 @@ struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral) return driver->md_session_map[peripheral]; } /* * diag_md_session_match_pid_peripheral * * 1. Pass valid PID and get all the peripherals in logging session * for that PID * 2. Pass valid Peipheral and get the pid logging for that peripheral * */ int diag_md_session_match_pid_peripheral(int pid, uint8_t peripheral) { int i, flag = 0; if (pid <= 0 || peripheral >= NUM_MD_SESSIONS) return -EINVAL; if (!peripheral) { for (i = 0; i < NUM_MD_SESSIONS; i++) { if (driver->md_session_map[i] && driver->md_session_map[i]->pid == pid) { peripheral |= 1 << i; flag = 1; } } if (flag) return peripheral; } if (!pid) { if (driver->md_session_map[peripheral]) return driver->md_session_map[peripheral]->pid; } return -EINVAL; } static int diag_md_peripheral_switch(int pid, int peripheral_mask, int req_mode) { int i, bit = 0; Loading Loading @@ -1637,6 +1664,13 @@ static int diag_md_session_check(int curr_mode, int req_mode, } err = diag_md_session_create(DIAG_MD_PERIPHERAL, param->peripheral_mask, DIAG_LOCAL_PROC); mutex_lock(&driver->hdlc_disable_mutex); for (i = 0; i < NUM_MD_SESSIONS; i++) { if ((param->peripheral_mask > 0) && (param->peripheral_mask & (1 << i))) driver->p_hdlc_disabled[i] = 0; } mutex_unlock(&driver->hdlc_disable_mutex); } *change_mode = 1; return err; Loading Loading @@ -2085,11 +2119,14 @@ static int diag_ioctl_dci_support(unsigned long ioarg) static int diag_ioctl_hdlc_toggle(unsigned long ioarg) { uint8_t hdlc_support; uint8_t hdlc_support, i; int peripheral = -EINVAL; struct diag_md_session_t *session_info = NULL; if (copy_from_user(&hdlc_support, (void __user *)ioarg, sizeof(uint8_t))) return -EFAULT; mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); Loading @@ -2097,6 +2134,25 @@ static int diag_ioctl_hdlc_toggle(unsigned long ioarg) session_info->hdlc_disabled = hdlc_support; else driver->hdlc_disabled = hdlc_support; peripheral = diag_md_session_match_pid_peripheral(current->tgid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && session_info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = session_info->hdlc_disabled; else if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); diag_update_md_clients(HDLC_SUPPORT_TYPE); Loading Loading @@ -2970,7 +3026,6 @@ 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) { Loading Loading @@ -3024,13 +3079,7 @@ static int diag_user_process_apps_data(const char __user *buf, int len, mutex_lock(&apps_data_mutex); mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(APPS_DATA); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA]; if (hdlc_disabled) ret = diag_process_apps_data_non_hdlc(user_space_data, len, pkt_type); Loading
drivers/char/diag/diagfwd.c +134 −12 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ #define STM_RSP_STATUS_INDEX 8 #define STM_RSP_NUM_BYTES 9 struct diag_md_hdlc_reset_work { int pid; struct work_struct work; }; static int timestamp_switch; module_param(timestamp_switch, int, 0644); Loading Loading @@ -436,6 +441,7 @@ static void diag_send_rsp(unsigned char *buf, int len, int pid) { struct diag_md_session_t *session_info = NULL, *info = NULL; uint8_t hdlc_disabled; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); session_info = (info) ? info : Loading @@ -445,6 +451,7 @@ static void diag_send_rsp(unsigned char *buf, int len, int pid) else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); if (hdlc_disabled) pack_rsp_and_send(buf, len, pid); else Loading Loading @@ -948,7 +955,7 @@ void diag_send_error_rsp(unsigned char *buf, int len, int diag_process_apps_pkt(unsigned char *buf, int len, int pid) { int i, p_mask = 0; int mask_ret; int mask_ret, peripheral = -EINVAL; int write_len = 0; unsigned char *temp = NULL; struct diag_cmd_reg_entry_t entry; Loading Loading @@ -1175,6 +1182,22 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) info->hdlc_disabled = 1; else driver->hdlc_disabled = 1; peripheral = diag_md_session_match_pid_peripheral(pid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = info->hdlc_disabled; else if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); diag_update_md_clients(HDLC_SUPPORT_TYPE); mutex_unlock(&driver->hdlc_disable_mutex); Loading Loading @@ -1350,8 +1373,17 @@ 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) if (driver->md_session_mode == DIAG_MD_NONE) { driver->hdlc_disabled = 0; /* * HDLC encoding is re-enabled when * there is logical/physical disconnection of diag * to USB. */ for (i = 0; i < NUM_MD_SESSIONS; i++) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } mutex_unlock(&driver->hdlc_disable_mutex); queue_work(driver->diag_wq, &(driver->update_user_clients)); Loading @@ -1366,6 +1398,7 @@ static uint8_t hdlc_reset; static void hdlc_reset_timer_start(int pid) { struct diag_md_session_t *info = NULL; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); if (!hdlc_timer_in_progress) { Loading @@ -1380,30 +1413,99 @@ static void hdlc_reset_timer_start(int pid) mutex_unlock(&driver->md_session_lock); } /* * diag_timer_work_fn * Queued in workqueue to protect md_session_info structure * * Update hdlc_disabled for each peripheral * which are not in any md_session_info. * */ static void diag_timer_work_fn(struct work_struct *work) { int i = 0; struct diag_md_session_t *session_info = NULL; mutex_lock(&driver->hdlc_disable_mutex); driver->hdlc_disabled = 0; mutex_lock(&driver->md_session_lock); for (i = 0; i < NUM_MD_SESSIONS; i++) { session_info = diag_md_session_get_peripheral(i); if (!session_info) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); } /* * diag_md_timer_work_fn * Queued in workqueue to protect md_session_info structure * * Update hdlc_disabled for each peripheral * which are in any md_session_info * */ static void diag_md_timer_work_fn(struct work_struct *work) { int peripheral = -EINVAL, i = 0; struct diag_md_session_t *session_info = NULL; struct diag_md_hdlc_reset_work *hdlc_work = container_of(work, struct diag_md_hdlc_reset_work, work); if (!hdlc_work) return; mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(hdlc_work->pid); if (session_info) session_info->hdlc_disabled = 0; peripheral = diag_md_session_match_pid_peripheral(hdlc_work->pid, 0); if (peripheral > 0 && session_info) { for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = session_info->hdlc_disabled; } } kfree(hdlc_work); mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); } static void hdlc_reset_timer_func(unsigned long data) { pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); if (hdlc_reset) { driver->hdlc_disabled = 0; queue_work(driver->diag_wq, &(driver->update_user_clients)); queue_work(driver->diag_wq, &(driver->diag_hdlc_reset_work)); queue_work(driver->diag_wq, &(driver->update_user_clients)); } hdlc_timer_in_progress = 0; } void diag_md_hdlc_reset_timer_func(unsigned long pid) { struct diag_md_session_t *session_info = NULL; struct diag_md_hdlc_reset_work *hdlc_reset_work = NULL; pr_debug("diag: In %s, re-enabling HDLC encoding\n", __func__); hdlc_reset_work = kmalloc(sizeof(*hdlc_reset_work), GFP_ATOMIC); if (!hdlc_reset_work) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: Could not allocate hdlc_reset_work\n"); hdlc_timer_in_progress = 0; return; } 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_reset_work->pid = pid; INIT_WORK(&hdlc_reset_work->work, diag_md_timer_work_fn); queue_work(driver->diag_wq, &(hdlc_reset_work->work)); queue_work(driver->diag_wq, &(driver->update_md_clients)); } hdlc_timer_in_progress = 0; } Loading @@ -1411,7 +1513,7 @@ void diag_md_hdlc_reset_timer_func(unsigned long pid) static void diag_hdlc_start_recovery(unsigned char *buf, int len, int pid) { int i; int i, peripheral = -EINVAL; static uint32_t bad_byte_counter; unsigned char *start_ptr = NULL; struct diag_pkt_frame_t *actual_pkt = NULL; Loading Loading @@ -1443,6 +1545,24 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, info->hdlc_disabled = 0; else driver->hdlc_disabled = 0; peripheral = diag_md_session_match_pid_peripheral(pid, 0); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (peripheral > 0 && info) { if (peripheral & (1 << i)) driver->p_hdlc_disabled[i] = info->hdlc_disabled; else if ( !diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } else { if (!diag_md_session_get_peripheral(i)) driver->p_hdlc_disabled[i] = driver->hdlc_disabled; } } mutex_unlock(&driver->md_session_lock); mutex_unlock(&driver->hdlc_disable_mutex); diag_update_md_clients(HDLC_SUPPORT_TYPE); Loading Loading @@ -1700,6 +1820,8 @@ int diagfwd_init(void) INIT_LIST_HEAD(&driver->cmd_reg_list); driver->cmd_reg_count = 0; mutex_init(&driver->cmd_reg_mutex); INIT_WORK(&(driver->diag_hdlc_reset_work), diag_timer_work_fn); for (i = 0; i < NUM_PERIPHERALS; i++) { driver->feature[i].separate_cmd_rsp = 0; Loading
drivers/char/diag/diagfwd_peripheral.c +6 −16 Original line number Diff line number Diff line Loading @@ -284,7 +284,6 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info, int err = 0; int write_len = 0, peripheral = 0; unsigned char *write_buf = NULL; struct diag_md_session_t *session_info = NULL; uint8_t hdlc_disabled = 0; if (!fwd_info || !buf || len <= 0) { Loading Loading @@ -316,13 +315,9 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info, diag_ws_release(); return; } mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(peripheral); if (session_info) hdlc_disabled = session_info->hdlc_disabled; else hdlc_disabled = driver->hdlc_disabled; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[peripheral]; if (hdlc_disabled) { /* The data is raw and and on APPS side HDLC is disabled */ if (!buf) { Loading Loading @@ -615,7 +610,6 @@ 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) { Loading @@ -637,13 +631,9 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&fwd_info->data_mutex); mutex_lock(&driver->md_session_lock); 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; mutex_unlock(&driver->md_session_lock); hdlc_disabled = driver->p_hdlc_disabled[fwd_info->peripheral]; 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