Loading drivers/char/diag/diag_masks.c +4 −4 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id) mutex_unlock(&mask->lock); err = diagfwd_write(peripheral, TYPE_CNTL, buf, header_len + mask_size); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send log masks to peripheral %d, equip_id: %d, err: %d\n", peripheral, i, err); } Loading Loading @@ -236,7 +236,7 @@ static void diag_send_event_mask_update(uint8_t peripheral) write_len += sizeof(header); err = diagfwd_write(peripheral, TYPE_CNTL, buf, write_len); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send event masks to peripheral %d\n", peripheral); } Loading Loading @@ -327,7 +327,7 @@ proceed: err = diagfwd_write(peripheral, TYPE_CNTL, buf, header_len + mask_size); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send msg masks to peripheral %d\n", peripheral); } Loading Loading @@ -382,7 +382,7 @@ static void diag_send_feature_mask_update(uint8_t peripheral) total_len = header_size + FEATURE_MASK_LEN; err = diagfwd_write(peripheral, TYPE_CNTL, buf, total_len); if (err) { if (err && err != -ENODEV) { pr_err("diag: In %s, unable to write to peripheral: %d, type: %d, len: %d, err: %d\n", __func__, peripheral, TYPE_CNTL, total_len, err); Loading drivers/char/diag/diagchar.h +18 −3 Original line number Diff line number Diff line Loading @@ -97,9 +97,15 @@ #define DIAG_CMD_QUERY_TMC 0x02 #define DIAG_SS_TDSCDMA 0x57 #define DIAG_CMD_TDSCDMA_STATUS 0x0E #define DIAG_CMD_DIAG_SUBSYS_DELAY 0x80 #define DIAG_SS_DIAG 0x12 #define DIAG_SS_PARAMS 0x32 #define DIAG_SS_FILE_READ_MODEM 0x0816 #define DIAG_SS_FILE_READ_ADSP 0x0E10 #define DIAG_SS_FILE_READ_WCNSS 0x141F #define DIAG_SS_FILE_READ_SLPI 0x01A18 #define DIAG_SS_FILE_READ_APPS 0x020F #define DIAG_DIAG_MAX_PKT_SZ 0x55 #define DIAG_DIAG_STM 0x214 Loading Loading @@ -240,7 +246,8 @@ struct diag_cmd_ext_mobile_rsp_t { uint8_t version; uint8_t padding[3]; uint32_t family; }; uint32_t chip_id; } __packed; struct diag_cmd_reg_entry_t { uint16_t cmd_code; Loading Loading @@ -380,6 +387,13 @@ struct diag_feature_t { uint8_t sent_feature_mask; }; struct diag_mdlog_client_info { struct task_struct *client_process; int client_id; uint16_t notification_list; int signal_type; }; struct diagchar_dev { /* State for the char driver */ Loading Loading @@ -491,6 +505,7 @@ struct diagchar_dev { int logging_mode; int mask_check; struct diag_md_proc_info md_proc[DIAG_NUM_PROC]; struct diag_mdlog_client_info md_client_info; /* Power related variables */ struct diag_ws_ref_t dci_ws; struct diag_ws_ref_t md_ws; Loading @@ -509,8 +524,8 @@ struct diagchar_dev { uint32_t max_ssid_count[NUM_PERIPHERALS]; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* For sending command requests in callback mode */ unsigned char *cb_buf; int cb_buf_len; unsigned char *hdlc_encode_buf; int hdlc_encode_buf_len; #endif }; Loading drivers/char/diag/diagchar_core.c +83 −97 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ struct diagchar_priv { int pid; }; #define CALLBACK_NON_HDLC_DATA 0 #define CALLBACK_HDLC_DATA 1 #define USER_SPACE_RAW_DATA 0 #define USER_SPACE_HDLC_DATA 1 /* Memory pool variables */ /* Used for copying any incoming packet from user space clients. */ Loading Loading @@ -376,6 +376,8 @@ static void diag_close_logging_process(int pid) if (logging_proc->callback_process) logging_proc->callback_process = NULL; logging_proc->pid = 0; if (driver->md_client_info.client_process) driver->md_client_info.client_process = NULL; diag_update_proc_vote(DIAG_PROC_MEMORY_DEVICE, VOTE_DOWN, i); } mutex_unlock(&driver->diagchar_mutex); Loading Loading @@ -844,19 +846,19 @@ static int diag_remote_init(void) poolsize_mdm_dci_write); diagmem_setsize(POOL_TYPE_QSC_MUX, itemsize_qsc_usb, poolsize_qsc_usb); driver->cb_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL); if (!driver->cb_buf) driver->hdlc_encode_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL); if (!driver->hdlc_encode_buf) return -ENOMEM; driver->cb_buf_len = 0; driver->hdlc_encode_buf_len = 0; return 0; } static void diag_remote_exit(void) { kfree(driver->cb_buf); kfree(driver->hdlc_encode_buf); } static int diag_cb_send_data_remote(int proc, void *buf, int len, static int diag_send_raw_data_remote(int proc, void *buf, int len, uint8_t hdlc_flag) { int err = 0; Loading @@ -866,6 +868,7 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, uint16_t payload = 0; 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; if (!buf) return -EINVAL; Loading @@ -875,24 +878,30 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, return -EBADMSG; } if (bridge_index < 0 || bridge_index > NUM_REMOTE_DEV) { pr_err("diag: In %s, invalid bridge index: %d\n", __func__, bridge_index); return -EINVAL; } do { if (driver->cb_buf_len == 0) if (driver->hdlc_encode_buf_len == 0) break; usleep_range(10000, 10100); retry_count++; } while (retry_count < max_retries); if (driver->cb_buf_len != 0) if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; if (driver->hdlc_disabled) { payload = *(uint16_t *)(buf + 2); driver->cb_buf_len = payload; driver->hdlc_encode_buf_len = payload; /* * Adding 4 bytes for start (1 byte), version (1 byte) and * payload (2 bytes) */ memcpy(driver->cb_buf, buf + 4, payload); memcpy(driver->hdlc_encode_buf, buf + 4, payload); goto send_data; } Loading @@ -902,8 +911,8 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, len); return -EBADMSG; } driver->cb_buf_len = len; memcpy(driver->cb_buf, buf, len); driver->hdlc_encode_buf_len = len; memcpy(driver->hdlc_encode_buf, buf, len); goto send_data; } Loading @@ -924,18 +933,19 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, send.last = (void *)(buf + len - 1); send.terminate = 1; enc.dest = driver->cb_buf; enc.dest_last = (void *)(driver->cb_buf + max_len - 1); enc.dest = driver->hdlc_encode_buf; enc.dest_last = (void *)(driver->hdlc_encode_buf + max_len - 1); diag_hdlc_encode(&send, &enc); driver->cb_buf_len = (int)(enc.dest - (void *)driver->cb_buf); driver->hdlc_encode_buf_len = (int)(enc.dest - (void *)driver->hdlc_encode_buf); send_data: err = diagfwd_bridge_write(proc, driver->cb_buf, driver->cb_buf_len); err = diagfwd_bridge_write(proc, driver->hdlc_encode_buf, driver->hdlc_encode_buf_len); if (err) { pr_err_ratelimited("diag: Error writing Callback packet to proc: %d, err: %d\n", proc, err); driver->cb_buf_len = 0; driver->hdlc_encode_buf_len = 0; } return err; Loading Loading @@ -986,7 +996,7 @@ uint16_t diag_get_remote_device_mask(void) return 0; } static int diag_cb_send_data_remote(int proc, void *buf, int len, static int diag_send_raw_data_remote(int proc, void *buf, int len, uint8_t hdlc_flag) { return -EINVAL; Loading @@ -1006,7 +1016,22 @@ static int mask_request_validate(unsigned char mask_buf[]) packet_id = mask_buf[0]; if (packet_id == 0x4B) { if (packet_id == DIAG_CMD_DIAG_SUBSYS_DELAY) { subsys_id = mask_buf[1]; ss_cmd = *(uint16_t *)(mask_buf + 2); switch (subsys_id) { case DIAG_SS_DIAG: if ((ss_cmd == DIAG_SS_FILE_READ_MODEM) || (ss_cmd == DIAG_SS_FILE_READ_ADSP) || (ss_cmd == DIAG_SS_FILE_READ_WCNSS) || (ss_cmd == DIAG_SS_FILE_READ_SLPI) || (ss_cmd == DIAG_SS_FILE_READ_APPS)) return 1; break; default: return 0; } } else if (packet_id == 0x4B) { subsys_id = mask_buf[1]; ss_cmd = *(uint16_t *)(mask_buf + 2); /* Packets with SSID which are allowed */ Loading Loading @@ -1113,6 +1138,10 @@ static int diag_switch_logging(int requested_mode) driver->md_proc[DIAG_LOCAL_PROC].socket_process = NULL; } if (new_mode == MEMORY_DEVICE_MODE) driver->md_client_info.client_process = current; mutex_lock(&driver->diagchar_mutex); diag_ws_reset(DIAG_WS_MUX); err = diag_mux_switch_logging(mux_mode); if (err) { Loading Loading @@ -1974,7 +2003,7 @@ fail: return err; } static int diag_user_process_callback_data(const char __user *buf, int len) static int diag_user_process_raw_data(const char __user *buf, int len) { int err = 0; int ret = 0; Loading @@ -2001,82 +2030,41 @@ static int diag_user_process_callback_data(const char __user *buf, int len) /* Check for proc_type */ remote_proc = diag_get_remote(*(int *)user_space_data); if (!remote_proc) { wait_event_interruptible(driver->wait_q, (driver->in_busy_pktdata == 0)); ret = diag_process_apps_pkt(user_space_data, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return ret; } if (remote_proc) { token_offset = sizeof(int); if (len <= MIN_SIZ_ALLOW) { pr_err("diag: In %s, possible integer underflow, payload size: %d\n", __func__, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return -EBADMSG; } len -= sizeof(int); ret = diag_cb_send_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, CALLBACK_NON_HDLC_DATA); fail: } if (driver->mask_check) { if (!mask_request_validate(user_space_data + token_offset)) { pr_alert("diag: mask request Invalid\n"); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return ret; return -EFAULT; } static int diag_user_process_callback_hdlc_data(const char __user *buf, int len) { int err = 0; int ret = 0; int token_offset = 0; int remote_proc = 0; const int mempool = POOL_TYPE_COPY; unsigned char *user_space_data = NULL; if (!buf || len <= 0 || len > CALLBACK_BUF_SIZE) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", __func__, buf, len); return -EBADMSG; } user_space_data = diagmem_alloc(driver, len, mempool); if (!user_space_data) return -ENOMEM; err = copy_from_user(user_space_data, buf, len); if (err) { pr_err("diag: copy failed for user space data\n"); goto fail; if (remote_proc) { ret = diag_send_raw_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, USER_SPACE_RAW_DATA); if (ret) { pr_err("diag: Error sending data to remote proc %d, err: %d\n", remote_proc, ret); } /* Check for proc_type */ remote_proc = diag_get_remote(*(int *)user_space_data); if (!remote_proc) { } else { wait_event_interruptible(driver->wait_q, (driver->in_busy_pktdata == 0)); if (driver->hdlc_disabled) diag_process_non_hdlc_pkt(user_space_data, len); else diag_process_hdlc_pkt((void *)user_space_data, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return 0; } token_offset = sizeof(int); if (len <= MIN_SIZ_ALLOW) { pr_err("diag: In %s, possible integer underflow, payload size: %d\n", __func__, len); return -EBADMSG; ret = diag_process_apps_pkt(user_space_data, len); if (ret == 1) diag_send_error_rsp((void *)(user_space_data), len); } len -= sizeof(int); ret = diag_cb_send_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, CALLBACK_HDLC_DATA); fail: diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; Loading Loading @@ -2463,11 +2451,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, pkt_type); else if (pkt_type == DCI_DATA_TYPE) return diag_user_process_dci_data(payload_buf, payload_len); else if (pkt_type == CALLBACK_DATA_TYPE) return diag_user_process_callback_data(payload_buf, payload_len); else if (pkt_type == CALLBACK_HDLC_DATA_TYPE) return diag_user_process_callback_hdlc_data(payload_buf, else if (pkt_type == USER_SPACE_RAW_DATA_TYPE) return diag_user_process_raw_data(payload_buf, payload_len); else if (pkt_type == USER_SPACE_DATA_TYPE) return diag_user_process_userspace_data(payload_buf, Loading Loading @@ -2831,6 +2816,7 @@ static int __init diagchar_init(void) driver->md_proc[i].callback_process = NULL; driver->md_proc[i].socket_process = NULL; } driver->md_client_info.client_process = NULL; driver->mask_check = 0; driver->in_busy_pktdata = 0; driver->in_busy_dcipktdata = 0; Loading drivers/char/diag/diagfwd.c +5 −4 Original line number Diff line number Diff line Loading @@ -606,11 +606,12 @@ int diag_cmd_get_mobile_id(unsigned char *src_buf, int src_len, rsp.header.cmd_code = header->cmd_code; rsp.header.subsys_id = header->subsys_id; rsp.header.subsys_cmd_code = header->subsys_cmd_code; rsp.version = 1; rsp.version = 2; rsp.padding[0] = 0; rsp.padding[1] = 0; rsp.padding[2] = 0; rsp.family = (uint32_t)socinfo_get_msm_cpu(); rsp.family = 0; rsp.chip_id = (uint32_t)socinfo_get_id(); memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); Loading Loading @@ -719,7 +720,7 @@ static int diag_cmd_disable_hdlc(unsigned char *src_buf, int src_len, return write_len; } static void diag_send_error_rsp(unsigned char *buf, int len) void diag_send_error_rsp(unsigned char *buf, int len) { /* -1 to accomodate the first byte 0x13 */ if (len > (DIAG_MAX_RSP_SIZE - 1)) { Loading Loading @@ -856,7 +857,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len) driver->apps_rsp_buf, DIAG_MAX_RSP_SIZE); if (write_len > 0) { diag_send_rsp(driver->apps_rsp_buf, write_len - 1); diag_send_rsp(driver->apps_rsp_buf, write_len); return 0; } } Loading drivers/char/diag/diagfwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ int diag_check_common_cmd(struct diag_pkt_header_t *header); void diag_update_userspace_clients(unsigned int type); void diag_update_sleeping_process(int process_id, int data_type); 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); #endif Loading
drivers/char/diag/diag_masks.c +4 −4 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id) mutex_unlock(&mask->lock); err = diagfwd_write(peripheral, TYPE_CNTL, buf, header_len + mask_size); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send log masks to peripheral %d, equip_id: %d, err: %d\n", peripheral, i, err); } Loading Loading @@ -236,7 +236,7 @@ static void diag_send_event_mask_update(uint8_t peripheral) write_len += sizeof(header); err = diagfwd_write(peripheral, TYPE_CNTL, buf, write_len); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send event masks to peripheral %d\n", peripheral); } Loading Loading @@ -327,7 +327,7 @@ proceed: err = diagfwd_write(peripheral, TYPE_CNTL, buf, header_len + mask_size); if (err) { if (err && err != -ENODEV) { pr_err("diag: Unable to send msg masks to peripheral %d\n", peripheral); } Loading Loading @@ -382,7 +382,7 @@ static void diag_send_feature_mask_update(uint8_t peripheral) total_len = header_size + FEATURE_MASK_LEN; err = diagfwd_write(peripheral, TYPE_CNTL, buf, total_len); if (err) { if (err && err != -ENODEV) { pr_err("diag: In %s, unable to write to peripheral: %d, type: %d, len: %d, err: %d\n", __func__, peripheral, TYPE_CNTL, total_len, err); Loading
drivers/char/diag/diagchar.h +18 −3 Original line number Diff line number Diff line Loading @@ -97,9 +97,15 @@ #define DIAG_CMD_QUERY_TMC 0x02 #define DIAG_SS_TDSCDMA 0x57 #define DIAG_CMD_TDSCDMA_STATUS 0x0E #define DIAG_CMD_DIAG_SUBSYS_DELAY 0x80 #define DIAG_SS_DIAG 0x12 #define DIAG_SS_PARAMS 0x32 #define DIAG_SS_FILE_READ_MODEM 0x0816 #define DIAG_SS_FILE_READ_ADSP 0x0E10 #define DIAG_SS_FILE_READ_WCNSS 0x141F #define DIAG_SS_FILE_READ_SLPI 0x01A18 #define DIAG_SS_FILE_READ_APPS 0x020F #define DIAG_DIAG_MAX_PKT_SZ 0x55 #define DIAG_DIAG_STM 0x214 Loading Loading @@ -240,7 +246,8 @@ struct diag_cmd_ext_mobile_rsp_t { uint8_t version; uint8_t padding[3]; uint32_t family; }; uint32_t chip_id; } __packed; struct diag_cmd_reg_entry_t { uint16_t cmd_code; Loading Loading @@ -380,6 +387,13 @@ struct diag_feature_t { uint8_t sent_feature_mask; }; struct diag_mdlog_client_info { struct task_struct *client_process; int client_id; uint16_t notification_list; int signal_type; }; struct diagchar_dev { /* State for the char driver */ Loading Loading @@ -491,6 +505,7 @@ struct diagchar_dev { int logging_mode; int mask_check; struct diag_md_proc_info md_proc[DIAG_NUM_PROC]; struct diag_mdlog_client_info md_client_info; /* Power related variables */ struct diag_ws_ref_t dci_ws; struct diag_ws_ref_t md_ws; Loading @@ -509,8 +524,8 @@ struct diagchar_dev { uint32_t max_ssid_count[NUM_PERIPHERALS]; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* For sending command requests in callback mode */ unsigned char *cb_buf; int cb_buf_len; unsigned char *hdlc_encode_buf; int hdlc_encode_buf_len; #endif }; Loading
drivers/char/diag/diagchar_core.c +83 −97 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ struct diagchar_priv { int pid; }; #define CALLBACK_NON_HDLC_DATA 0 #define CALLBACK_HDLC_DATA 1 #define USER_SPACE_RAW_DATA 0 #define USER_SPACE_HDLC_DATA 1 /* Memory pool variables */ /* Used for copying any incoming packet from user space clients. */ Loading Loading @@ -376,6 +376,8 @@ static void diag_close_logging_process(int pid) if (logging_proc->callback_process) logging_proc->callback_process = NULL; logging_proc->pid = 0; if (driver->md_client_info.client_process) driver->md_client_info.client_process = NULL; diag_update_proc_vote(DIAG_PROC_MEMORY_DEVICE, VOTE_DOWN, i); } mutex_unlock(&driver->diagchar_mutex); Loading Loading @@ -844,19 +846,19 @@ static int diag_remote_init(void) poolsize_mdm_dci_write); diagmem_setsize(POOL_TYPE_QSC_MUX, itemsize_qsc_usb, poolsize_qsc_usb); driver->cb_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL); if (!driver->cb_buf) driver->hdlc_encode_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL); if (!driver->hdlc_encode_buf) return -ENOMEM; driver->cb_buf_len = 0; driver->hdlc_encode_buf_len = 0; return 0; } static void diag_remote_exit(void) { kfree(driver->cb_buf); kfree(driver->hdlc_encode_buf); } static int diag_cb_send_data_remote(int proc, void *buf, int len, static int diag_send_raw_data_remote(int proc, void *buf, int len, uint8_t hdlc_flag) { int err = 0; Loading @@ -866,6 +868,7 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, uint16_t payload = 0; 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; if (!buf) return -EINVAL; Loading @@ -875,24 +878,30 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, return -EBADMSG; } if (bridge_index < 0 || bridge_index > NUM_REMOTE_DEV) { pr_err("diag: In %s, invalid bridge index: %d\n", __func__, bridge_index); return -EINVAL; } do { if (driver->cb_buf_len == 0) if (driver->hdlc_encode_buf_len == 0) break; usleep_range(10000, 10100); retry_count++; } while (retry_count < max_retries); if (driver->cb_buf_len != 0) if (driver->hdlc_encode_buf_len != 0) return -EAGAIN; if (driver->hdlc_disabled) { payload = *(uint16_t *)(buf + 2); driver->cb_buf_len = payload; driver->hdlc_encode_buf_len = payload; /* * Adding 4 bytes for start (1 byte), version (1 byte) and * payload (2 bytes) */ memcpy(driver->cb_buf, buf + 4, payload); memcpy(driver->hdlc_encode_buf, buf + 4, payload); goto send_data; } Loading @@ -902,8 +911,8 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, len); return -EBADMSG; } driver->cb_buf_len = len; memcpy(driver->cb_buf, buf, len); driver->hdlc_encode_buf_len = len; memcpy(driver->hdlc_encode_buf, buf, len); goto send_data; } Loading @@ -924,18 +933,19 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len, send.last = (void *)(buf + len - 1); send.terminate = 1; enc.dest = driver->cb_buf; enc.dest_last = (void *)(driver->cb_buf + max_len - 1); enc.dest = driver->hdlc_encode_buf; enc.dest_last = (void *)(driver->hdlc_encode_buf + max_len - 1); diag_hdlc_encode(&send, &enc); driver->cb_buf_len = (int)(enc.dest - (void *)driver->cb_buf); driver->hdlc_encode_buf_len = (int)(enc.dest - (void *)driver->hdlc_encode_buf); send_data: err = diagfwd_bridge_write(proc, driver->cb_buf, driver->cb_buf_len); err = diagfwd_bridge_write(proc, driver->hdlc_encode_buf, driver->hdlc_encode_buf_len); if (err) { pr_err_ratelimited("diag: Error writing Callback packet to proc: %d, err: %d\n", proc, err); driver->cb_buf_len = 0; driver->hdlc_encode_buf_len = 0; } return err; Loading Loading @@ -986,7 +996,7 @@ uint16_t diag_get_remote_device_mask(void) return 0; } static int diag_cb_send_data_remote(int proc, void *buf, int len, static int diag_send_raw_data_remote(int proc, void *buf, int len, uint8_t hdlc_flag) { return -EINVAL; Loading @@ -1006,7 +1016,22 @@ static int mask_request_validate(unsigned char mask_buf[]) packet_id = mask_buf[0]; if (packet_id == 0x4B) { if (packet_id == DIAG_CMD_DIAG_SUBSYS_DELAY) { subsys_id = mask_buf[1]; ss_cmd = *(uint16_t *)(mask_buf + 2); switch (subsys_id) { case DIAG_SS_DIAG: if ((ss_cmd == DIAG_SS_FILE_READ_MODEM) || (ss_cmd == DIAG_SS_FILE_READ_ADSP) || (ss_cmd == DIAG_SS_FILE_READ_WCNSS) || (ss_cmd == DIAG_SS_FILE_READ_SLPI) || (ss_cmd == DIAG_SS_FILE_READ_APPS)) return 1; break; default: return 0; } } else if (packet_id == 0x4B) { subsys_id = mask_buf[1]; ss_cmd = *(uint16_t *)(mask_buf + 2); /* Packets with SSID which are allowed */ Loading Loading @@ -1113,6 +1138,10 @@ static int diag_switch_logging(int requested_mode) driver->md_proc[DIAG_LOCAL_PROC].socket_process = NULL; } if (new_mode == MEMORY_DEVICE_MODE) driver->md_client_info.client_process = current; mutex_lock(&driver->diagchar_mutex); diag_ws_reset(DIAG_WS_MUX); err = diag_mux_switch_logging(mux_mode); if (err) { Loading Loading @@ -1974,7 +2003,7 @@ fail: return err; } static int diag_user_process_callback_data(const char __user *buf, int len) static int diag_user_process_raw_data(const char __user *buf, int len) { int err = 0; int ret = 0; Loading @@ -2001,82 +2030,41 @@ static int diag_user_process_callback_data(const char __user *buf, int len) /* Check for proc_type */ remote_proc = diag_get_remote(*(int *)user_space_data); if (!remote_proc) { wait_event_interruptible(driver->wait_q, (driver->in_busy_pktdata == 0)); ret = diag_process_apps_pkt(user_space_data, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return ret; } if (remote_proc) { token_offset = sizeof(int); if (len <= MIN_SIZ_ALLOW) { pr_err("diag: In %s, possible integer underflow, payload size: %d\n", __func__, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return -EBADMSG; } len -= sizeof(int); ret = diag_cb_send_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, CALLBACK_NON_HDLC_DATA); fail: } if (driver->mask_check) { if (!mask_request_validate(user_space_data + token_offset)) { pr_alert("diag: mask request Invalid\n"); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return ret; return -EFAULT; } static int diag_user_process_callback_hdlc_data(const char __user *buf, int len) { int err = 0; int ret = 0; int token_offset = 0; int remote_proc = 0; const int mempool = POOL_TYPE_COPY; unsigned char *user_space_data = NULL; if (!buf || len <= 0 || len > CALLBACK_BUF_SIZE) { pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n", __func__, buf, len); return -EBADMSG; } user_space_data = diagmem_alloc(driver, len, mempool); if (!user_space_data) return -ENOMEM; err = copy_from_user(user_space_data, buf, len); if (err) { pr_err("diag: copy failed for user space data\n"); goto fail; if (remote_proc) { ret = diag_send_raw_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, USER_SPACE_RAW_DATA); if (ret) { pr_err("diag: Error sending data to remote proc %d, err: %d\n", remote_proc, ret); } /* Check for proc_type */ remote_proc = diag_get_remote(*(int *)user_space_data); if (!remote_proc) { } else { wait_event_interruptible(driver->wait_q, (driver->in_busy_pktdata == 0)); if (driver->hdlc_disabled) diag_process_non_hdlc_pkt(user_space_data, len); else diag_process_hdlc_pkt((void *)user_space_data, len); diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; return 0; } token_offset = sizeof(int); if (len <= MIN_SIZ_ALLOW) { pr_err("diag: In %s, possible integer underflow, payload size: %d\n", __func__, len); return -EBADMSG; ret = diag_process_apps_pkt(user_space_data, len); if (ret == 1) diag_send_error_rsp((void *)(user_space_data), len); } len -= sizeof(int); ret = diag_cb_send_data_remote(remote_proc - 1, (void *)(user_space_data + token_offset), len, CALLBACK_HDLC_DATA); fail: diagmem_free(driver, user_space_data, mempool); user_space_data = NULL; Loading Loading @@ -2463,11 +2451,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, pkt_type); else if (pkt_type == DCI_DATA_TYPE) return diag_user_process_dci_data(payload_buf, payload_len); else if (pkt_type == CALLBACK_DATA_TYPE) return diag_user_process_callback_data(payload_buf, payload_len); else if (pkt_type == CALLBACK_HDLC_DATA_TYPE) return diag_user_process_callback_hdlc_data(payload_buf, else if (pkt_type == USER_SPACE_RAW_DATA_TYPE) return diag_user_process_raw_data(payload_buf, payload_len); else if (pkt_type == USER_SPACE_DATA_TYPE) return diag_user_process_userspace_data(payload_buf, Loading Loading @@ -2831,6 +2816,7 @@ static int __init diagchar_init(void) driver->md_proc[i].callback_process = NULL; driver->md_proc[i].socket_process = NULL; } driver->md_client_info.client_process = NULL; driver->mask_check = 0; driver->in_busy_pktdata = 0; driver->in_busy_dcipktdata = 0; Loading
drivers/char/diag/diagfwd.c +5 −4 Original line number Diff line number Diff line Loading @@ -606,11 +606,12 @@ int diag_cmd_get_mobile_id(unsigned char *src_buf, int src_len, rsp.header.cmd_code = header->cmd_code; rsp.header.subsys_id = header->subsys_id; rsp.header.subsys_cmd_code = header->subsys_cmd_code; rsp.version = 1; rsp.version = 2; rsp.padding[0] = 0; rsp.padding[1] = 0; rsp.padding[2] = 0; rsp.family = (uint32_t)socinfo_get_msm_cpu(); rsp.family = 0; rsp.chip_id = (uint32_t)socinfo_get_id(); memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); Loading Loading @@ -719,7 +720,7 @@ static int diag_cmd_disable_hdlc(unsigned char *src_buf, int src_len, return write_len; } static void diag_send_error_rsp(unsigned char *buf, int len) void diag_send_error_rsp(unsigned char *buf, int len) { /* -1 to accomodate the first byte 0x13 */ if (len > (DIAG_MAX_RSP_SIZE - 1)) { Loading Loading @@ -856,7 +857,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len) driver->apps_rsp_buf, DIAG_MAX_RSP_SIZE); if (write_len > 0) { diag_send_rsp(driver->apps_rsp_buf, write_len - 1); diag_send_rsp(driver->apps_rsp_buf, write_len); return 0; } } Loading
drivers/char/diag/diagfwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ int diag_check_common_cmd(struct diag_pkt_header_t *header); void diag_update_userspace_clients(unsigned int type); void diag_update_sleeping_process(int process_id, int data_type); 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); #endif