Loading drivers/char/diag/diag_dci.c +131 −67 Original line number Diff line number Diff line Loading @@ -433,15 +433,96 @@ static inline int __diag_dci_query_event_mask(struct diag_dci_client_tbl *entry, return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0; } static struct dci_pkt_req_entry_t *diag_register_dci_transaction(int uid) { struct dci_pkt_req_entry_t *entry = NULL; entry = kzalloc(sizeof(struct dci_pkt_req_entry_t), GFP_KERNEL); if (!entry) return NULL; mutex_lock(&driver->dci_mutex); driver->dci_tag++; entry->pid = current->tgid; entry->uid = uid; entry->tag = driver->dci_tag; list_add_tail(&entry->track, &driver->dci_req_list); mutex_unlock(&driver->dci_mutex); return entry; } static struct dci_pkt_req_entry_t *diag_dci_get_request_entry(int tag) { struct list_head *start, *temp; struct dci_pkt_req_entry_t *entry = NULL; list_for_each_safe(start, temp, &driver->dci_req_list) { entry = list_entry(start, struct dci_pkt_req_entry_t, track); if (entry->tag == tag) return entry; } return NULL; } static int diag_dci_remove_req_entry(unsigned char *buf, int len, struct dci_pkt_req_entry_t *entry) { uint16_t rsp_count = 0, delayed_rsp_id = 0; if (!buf || len <= 0 || !entry) { pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n", __func__, buf, len, entry); return -EIO; } /* It is an immediate response, delete it from the table */ if (*buf != 0x80) { list_del(&entry->track); kfree(entry); return 1; } /* It is a delayed response. Check if the length is valid */ if (len < MIN_DELAYED_RSP_LEN) { pr_err("diag: Invalid delayed rsp packet length %d\n", len); return -EINVAL; } /* * If the delayed response id field (uint16_t at byte 8) is 0 then * there is only one response and we can remove the request entry. */ delayed_rsp_id = *(uint16_t *)(buf + 8); if (delayed_rsp_id == 0) { list_del(&entry->track); kfree(entry); return 1; } /* * Check the response count field (uint16 at byte 10). The request * entry can be deleted it it is the last response in the sequence. * It is the last response in the sequence if the response count * is 1 or if the signed bit gets dropped. */ rsp_count = *(uint16_t *)(buf + 10); if (rsp_count > 0 && rsp_count < 0x1000) { list_del(&entry->track); kfree(entry); return 1; } return 0; } void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, int len) { int i = 0, index = -1, cmd_code_len = 1; int curr_client_pid = 0, write_len; int cmd_code_len = 1; int curr_client_pid = 0, write_len, *tag = NULL; struct diag_dci_client_tbl *entry = NULL; void *temp_buf = NULL; uint8_t recv_pkt_cmd_code; uint8_t recv_pkt_cmd_code, delete_flag = 0; struct diag_dci_buffer_t *rsp_buf = NULL; struct dci_pkt_req_entry_t *req_entry = NULL; recv_pkt_cmd_code = *(uint8_t *)(buf+4); if (recv_pkt_cmd_code != DCI_PKT_RSP_CODE) Loading @@ -460,22 +541,22 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, return; } pr_debug("diag: len = %d\n", write_len); /* look up DCI client with tag */ for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].tag == *(int *)(buf+(4+cmd_code_len))) { *(int *)(buf+4+cmd_code_len) = driver->req_tracking_tbl[i].uid; curr_client_pid = driver->req_tracking_tbl[i].pid; index = i; break; } } if (index == -1) { tag = (int *)(buf + (4 + cmd_code_len)); /* Retrieve the Tag field */ req_entry = diag_dci_get_request_entry(*tag); if (!req_entry) { pr_err("diag: No matching PID for DCI data\n"); return; } *tag = req_entry->uid; /* Replace the tag field with UID */ curr_client_pid = req_entry->pid; /* Remove the headers and send only the response to this function */ delete_flag = diag_dci_remove_req_entry(buf + 8 + cmd_code_len, len - (8 + cmd_code_len), req_entry); if (delete_flag < 0) return; entry = __diag_dci_get_client_entry(curr_client_pid); if (!entry) { Loading @@ -486,9 +567,14 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, rsp_buf = entry->buffers[smd_info->peripheral].buf_cmd; mutex_lock(&rsp_buf->data_mutex); if ((rsp_buf->data_len + 8 + write_len) > rsp_buf->capacity) { /* * Check if we can fit the data in the rsp buffer. The total length of * the rsp is the rsp length (write_len) + DCI_PKT_RSP_TYPE header (int) * + field for length (int) + delete_flag (uint8_t) */ if ((rsp_buf->data_len + 9 + write_len) > rsp_buf->capacity) { pr_alert("diag: create capacity for pkt rsp\n"); rsp_buf->capacity += 8 + write_len; rsp_buf->capacity += 9 + write_len; temp_buf = krealloc(rsp_buf->data, rsp_buf->capacity, GFP_KERNEL); if (!temp_buf) { Loading @@ -503,16 +589,14 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, rsp_buf->data_len += sizeof(int); *(int *)(rsp_buf->data + rsp_buf->data_len) = write_len; rsp_buf->data_len += sizeof(int); *(uint8_t *)(rsp_buf->data + rsp_buf->data_len) = delete_flag; rsp_buf->data_len += sizeof(uint8_t); memcpy(rsp_buf->data+rsp_buf->data_len, buf+4+cmd_code_len, write_len); rsp_buf->data_len += write_len; rsp_buf->data_source = smd_info->peripheral; smd_info->in_busy_1 = 1; mutex_unlock(&rsp_buf->data_mutex); /* delete immediate response entry */ if (smd_info->buf_in_1[8+cmd_code_len] != 0x80) driver->req_tracking_tbl[index].pid = 0; /* * Add directly to the list for writing responses to the * userspace as these shouldn't be buffered and shouldn't wait Loading Loading @@ -841,8 +925,8 @@ void diag_dci_notify_client(int peripheral_mask, int data) } } int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int index) static int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int tag) { int i, status = 0; unsigned int read_len = 0; Loading @@ -867,8 +951,7 @@ int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, driver->apps_dci_buf[1] = 1; /* version */ *(uint16_t *)(driver->apps_dci_buf + 2) = len + 4 + 1; /* length */ driver->apps_dci_buf[4] = DCI_PKT_RSP_CODE; *(int *)(driver->apps_dci_buf + 5) = driver->req_tracking_tbl[index].tag; *(int *)(driver->apps_dci_buf + 5) = tag; for (i = 0; i < len; i++) driver->apps_dci_buf[i+9] = *(buf+i); read_len += len; Loading Loading @@ -900,43 +983,18 @@ int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, return status; } int diag_register_dci_transaction(int uid) { int i, new_dci_client = 1, ret = -1; for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].pid == current->tgid) { new_dci_client = 0; break; } } mutex_lock(&driver->dci_mutex); /* Make an entry in kernel DCI table */ driver->dci_tag++; for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].pid == 0) { driver->req_tracking_tbl[i].pid = current->tgid; driver->req_tracking_tbl[i].uid = uid; driver->req_tracking_tbl[i].tag = driver->dci_tag; ret = i; break; } } mutex_unlock(&driver->dci_mutex); return ret; } int diag_process_dci_transaction(unsigned char *buf, int len) { unsigned char *temp = buf; uint16_t subsys_cmd_code, log_code, item_num; int subsys_id, cmd_code, ret = -1, index = -1, found = 0; int subsys_id, cmd_code, ret = -1, found = 0; struct diag_master_table entry; int count, set_mask, num_codes, bit_index, event_id, offset = 0, i; unsigned int byte_index, read_len = 0; uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask; uint8_t *event_mask_ptr; struct diag_dci_client_tbl *dci_entry = NULL; struct dci_pkt_req_entry_t *req_entry = NULL; if (!temp) { pr_err("diag: Invalid buffer in %s\n", __func__); Loading @@ -951,8 +1009,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) return -EIO; } /* enter this UID into kernel table and return index */ index = diag_register_dci_transaction(*(int *)temp); if (index < 0) { req_entry = diag_register_dci_transaction(*(int *)temp); if (!req_entry) { pr_alert("diag: registering new DCI transaction failed\n"); return DIAG_DCI_NO_REG; } Loading Loading @@ -981,8 +1039,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.subsys_id == subsys_id && entry.cmd_code_lo <= subsys_cmd_code && entry.cmd_code_hi >= subsys_cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); ret = diag_send_dci_pkt(entry, buf, len, req_entry->tag); } else if (entry.cmd_code == 255 && cmd_code == 75) { if (entry.subsys_id == subsys_id && Loading @@ -991,7 +1049,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.cmd_code_hi >= subsys_cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); buf, len, req_entry->tag); } } else if (entry.cmd_code == 255 && entry.subsys_id == 255) { Loading @@ -999,7 +1058,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.cmd_code_hi >= cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); buf, len, req_entry->tag); } } } Loading Loading @@ -1518,18 +1578,13 @@ int diag_dci_init(void) } } if (driver->req_tracking_tbl == NULL) { driver->req_tracking_tbl = kzalloc(dci_max_reg * sizeof(struct dci_pkt_req_tracking_tbl), GFP_KERNEL); if (driver->req_tracking_tbl == NULL) goto err; } if (driver->apps_dci_buf == NULL) { driver->apps_dci_buf = kzalloc(APPS_BUF_SIZE, GFP_KERNEL); if (driver->apps_dci_buf == NULL) goto err; } INIT_LIST_HEAD(&driver->dci_client_list); INIT_LIST_HEAD(&driver->dci_req_list); driver->diag_dci_wq = create_singlethread_workqueue("diag_dci_wq"); INIT_WORK(&dci_data_drain_work, dci_data_drain_work_fn); Loading @@ -1549,7 +1604,6 @@ int diag_dci_init(void) return DIAG_DCI_NO_ERROR; err: pr_err("diag: Could not initialize diag DCI buffers"); kfree(driver->req_tracking_tbl); kfree(driver->apps_dci_buf); for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) diag_smd_destructor(&driver->smd_dci[i]); Loading Loading @@ -1582,7 +1636,6 @@ void diag_dci_exit(void) platform_driver_unregister(&msm_diag_dci_cmd_driver); } kfree(driver->req_tracking_tbl); kfree(driver->apps_dci_buf); mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); Loading Loading @@ -1843,6 +1896,8 @@ int diag_dci_deinit_client() struct diag_dci_buf_peripheral_t *proc_buf = NULL; struct diag_dci_client_tbl *entry = diag_dci_get_client_entry(); struct diag_dci_buffer_t *buf_entry, *temp; struct list_head *start, *req_temp; struct dci_pkt_req_entry_t *req_entry = NULL; struct diag_smd_info *smd_info = NULL; if (!entry) Loading Loading @@ -1876,6 +1931,15 @@ int diag_dci_deinit_client() return ret; } list_for_each_safe(start, req_temp, &driver->dci_req_list) { req_entry = list_entry(start, struct dci_pkt_req_entry_t, track); if (req_entry->pid == current->tgid) { list_del(&req_entry->track); kfree(req_entry); } } /* Clean up any buffer that is pending write */ mutex_lock(&entry->write_buf_mutex); list_for_each_entry_safe(buf_entry, temp, &entry->list_write_buf, Loading drivers/char/diag/diag_dci.h +5 −4 Original line number Diff line number Diff line Loading @@ -49,17 +49,20 @@ #define DCI_MAX_LOG_CODES 16 #define DCI_MAX_ITEMS_PER_LOG_CODE 512 #define MIN_DELAYED_RSP_LEN 12 extern unsigned int dci_max_reg; extern unsigned int dci_max_clients; extern unsigned char dci_cumulative_log_mask[DCI_LOG_MASK_SIZE]; extern unsigned char dci_cumulative_event_mask[DCI_EVENT_MASK_SIZE]; extern struct mutex dci_health_mutex; struct dci_pkt_req_tracking_tbl { struct dci_pkt_req_entry_t { int pid; int uid; int tag; }; struct list_head track; } __packed; struct diag_dci_reg_tbl_t { uint32_t client_id; Loading Loading @@ -160,8 +163,6 @@ void diag_process_apps_dci_read_data(int data_type, void *buf, int recd_bytes); int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf, int recd_bytes); int diag_process_dci_transaction(unsigned char *buf, int len); int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int index); void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, int len); struct diag_dci_client_tbl *diag_dci_get_client_entry(void); Loading drivers/char/diag/diagchar.h +1 −1 Original line number Diff line number Diff line Loading @@ -314,7 +314,7 @@ struct diagchar_dev { /* Whether or not the peripheral supports STM */ int peripheral_supports_stm[NUM_SMD_CONTROL_CHANNELS]; /* DCI related variables */ struct dci_pkt_req_tracking_tbl *req_tracking_tbl; struct list_head dci_req_list; struct list_head dci_client_list; int dci_tag; int dci_client_id; Loading Loading
drivers/char/diag/diag_dci.c +131 −67 Original line number Diff line number Diff line Loading @@ -433,15 +433,96 @@ static inline int __diag_dci_query_event_mask(struct diag_dci_client_tbl *entry, return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0; } static struct dci_pkt_req_entry_t *diag_register_dci_transaction(int uid) { struct dci_pkt_req_entry_t *entry = NULL; entry = kzalloc(sizeof(struct dci_pkt_req_entry_t), GFP_KERNEL); if (!entry) return NULL; mutex_lock(&driver->dci_mutex); driver->dci_tag++; entry->pid = current->tgid; entry->uid = uid; entry->tag = driver->dci_tag; list_add_tail(&entry->track, &driver->dci_req_list); mutex_unlock(&driver->dci_mutex); return entry; } static struct dci_pkt_req_entry_t *diag_dci_get_request_entry(int tag) { struct list_head *start, *temp; struct dci_pkt_req_entry_t *entry = NULL; list_for_each_safe(start, temp, &driver->dci_req_list) { entry = list_entry(start, struct dci_pkt_req_entry_t, track); if (entry->tag == tag) return entry; } return NULL; } static int diag_dci_remove_req_entry(unsigned char *buf, int len, struct dci_pkt_req_entry_t *entry) { uint16_t rsp_count = 0, delayed_rsp_id = 0; if (!buf || len <= 0 || !entry) { pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n", __func__, buf, len, entry); return -EIO; } /* It is an immediate response, delete it from the table */ if (*buf != 0x80) { list_del(&entry->track); kfree(entry); return 1; } /* It is a delayed response. Check if the length is valid */ if (len < MIN_DELAYED_RSP_LEN) { pr_err("diag: Invalid delayed rsp packet length %d\n", len); return -EINVAL; } /* * If the delayed response id field (uint16_t at byte 8) is 0 then * there is only one response and we can remove the request entry. */ delayed_rsp_id = *(uint16_t *)(buf + 8); if (delayed_rsp_id == 0) { list_del(&entry->track); kfree(entry); return 1; } /* * Check the response count field (uint16 at byte 10). The request * entry can be deleted it it is the last response in the sequence. * It is the last response in the sequence if the response count * is 1 or if the signed bit gets dropped. */ rsp_count = *(uint16_t *)(buf + 10); if (rsp_count > 0 && rsp_count < 0x1000) { list_del(&entry->track); kfree(entry); return 1; } return 0; } void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, int len) { int i = 0, index = -1, cmd_code_len = 1; int curr_client_pid = 0, write_len; int cmd_code_len = 1; int curr_client_pid = 0, write_len, *tag = NULL; struct diag_dci_client_tbl *entry = NULL; void *temp_buf = NULL; uint8_t recv_pkt_cmd_code; uint8_t recv_pkt_cmd_code, delete_flag = 0; struct diag_dci_buffer_t *rsp_buf = NULL; struct dci_pkt_req_entry_t *req_entry = NULL; recv_pkt_cmd_code = *(uint8_t *)(buf+4); if (recv_pkt_cmd_code != DCI_PKT_RSP_CODE) Loading @@ -460,22 +541,22 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, return; } pr_debug("diag: len = %d\n", write_len); /* look up DCI client with tag */ for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].tag == *(int *)(buf+(4+cmd_code_len))) { *(int *)(buf+4+cmd_code_len) = driver->req_tracking_tbl[i].uid; curr_client_pid = driver->req_tracking_tbl[i].pid; index = i; break; } } if (index == -1) { tag = (int *)(buf + (4 + cmd_code_len)); /* Retrieve the Tag field */ req_entry = diag_dci_get_request_entry(*tag); if (!req_entry) { pr_err("diag: No matching PID for DCI data\n"); return; } *tag = req_entry->uid; /* Replace the tag field with UID */ curr_client_pid = req_entry->pid; /* Remove the headers and send only the response to this function */ delete_flag = diag_dci_remove_req_entry(buf + 8 + cmd_code_len, len - (8 + cmd_code_len), req_entry); if (delete_flag < 0) return; entry = __diag_dci_get_client_entry(curr_client_pid); if (!entry) { Loading @@ -486,9 +567,14 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, rsp_buf = entry->buffers[smd_info->peripheral].buf_cmd; mutex_lock(&rsp_buf->data_mutex); if ((rsp_buf->data_len + 8 + write_len) > rsp_buf->capacity) { /* * Check if we can fit the data in the rsp buffer. The total length of * the rsp is the rsp length (write_len) + DCI_PKT_RSP_TYPE header (int) * + field for length (int) + delete_flag (uint8_t) */ if ((rsp_buf->data_len + 9 + write_len) > rsp_buf->capacity) { pr_alert("diag: create capacity for pkt rsp\n"); rsp_buf->capacity += 8 + write_len; rsp_buf->capacity += 9 + write_len; temp_buf = krealloc(rsp_buf->data, rsp_buf->capacity, GFP_KERNEL); if (!temp_buf) { Loading @@ -503,16 +589,14 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, rsp_buf->data_len += sizeof(int); *(int *)(rsp_buf->data + rsp_buf->data_len) = write_len; rsp_buf->data_len += sizeof(int); *(uint8_t *)(rsp_buf->data + rsp_buf->data_len) = delete_flag; rsp_buf->data_len += sizeof(uint8_t); memcpy(rsp_buf->data+rsp_buf->data_len, buf+4+cmd_code_len, write_len); rsp_buf->data_len += write_len; rsp_buf->data_source = smd_info->peripheral; smd_info->in_busy_1 = 1; mutex_unlock(&rsp_buf->data_mutex); /* delete immediate response entry */ if (smd_info->buf_in_1[8+cmd_code_len] != 0x80) driver->req_tracking_tbl[index].pid = 0; /* * Add directly to the list for writing responses to the * userspace as these shouldn't be buffered and shouldn't wait Loading Loading @@ -841,8 +925,8 @@ void diag_dci_notify_client(int peripheral_mask, int data) } } int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int index) static int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int tag) { int i, status = 0; unsigned int read_len = 0; Loading @@ -867,8 +951,7 @@ int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, driver->apps_dci_buf[1] = 1; /* version */ *(uint16_t *)(driver->apps_dci_buf + 2) = len + 4 + 1; /* length */ driver->apps_dci_buf[4] = DCI_PKT_RSP_CODE; *(int *)(driver->apps_dci_buf + 5) = driver->req_tracking_tbl[index].tag; *(int *)(driver->apps_dci_buf + 5) = tag; for (i = 0; i < len; i++) driver->apps_dci_buf[i+9] = *(buf+i); read_len += len; Loading Loading @@ -900,43 +983,18 @@ int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, return status; } int diag_register_dci_transaction(int uid) { int i, new_dci_client = 1, ret = -1; for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].pid == current->tgid) { new_dci_client = 0; break; } } mutex_lock(&driver->dci_mutex); /* Make an entry in kernel DCI table */ driver->dci_tag++; for (i = 0; i < dci_max_reg; i++) { if (driver->req_tracking_tbl[i].pid == 0) { driver->req_tracking_tbl[i].pid = current->tgid; driver->req_tracking_tbl[i].uid = uid; driver->req_tracking_tbl[i].tag = driver->dci_tag; ret = i; break; } } mutex_unlock(&driver->dci_mutex); return ret; } int diag_process_dci_transaction(unsigned char *buf, int len) { unsigned char *temp = buf; uint16_t subsys_cmd_code, log_code, item_num; int subsys_id, cmd_code, ret = -1, index = -1, found = 0; int subsys_id, cmd_code, ret = -1, found = 0; struct diag_master_table entry; int count, set_mask, num_codes, bit_index, event_id, offset = 0, i; unsigned int byte_index, read_len = 0; uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask; uint8_t *event_mask_ptr; struct diag_dci_client_tbl *dci_entry = NULL; struct dci_pkt_req_entry_t *req_entry = NULL; if (!temp) { pr_err("diag: Invalid buffer in %s\n", __func__); Loading @@ -951,8 +1009,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) return -EIO; } /* enter this UID into kernel table and return index */ index = diag_register_dci_transaction(*(int *)temp); if (index < 0) { req_entry = diag_register_dci_transaction(*(int *)temp); if (!req_entry) { pr_alert("diag: registering new DCI transaction failed\n"); return DIAG_DCI_NO_REG; } Loading Loading @@ -981,8 +1039,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.subsys_id == subsys_id && entry.cmd_code_lo <= subsys_cmd_code && entry.cmd_code_hi >= subsys_cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); ret = diag_send_dci_pkt(entry, buf, len, req_entry->tag); } else if (entry.cmd_code == 255 && cmd_code == 75) { if (entry.subsys_id == subsys_id && Loading @@ -991,7 +1049,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.cmd_code_hi >= subsys_cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); buf, len, req_entry->tag); } } else if (entry.cmd_code == 255 && entry.subsys_id == 255) { Loading @@ -999,7 +1058,8 @@ int diag_process_dci_transaction(unsigned char *buf, int len) entry.cmd_code_hi >= cmd_code) { ret = diag_send_dci_pkt(entry, buf, len, index); buf, len, req_entry->tag); } } } Loading Loading @@ -1518,18 +1578,13 @@ int diag_dci_init(void) } } if (driver->req_tracking_tbl == NULL) { driver->req_tracking_tbl = kzalloc(dci_max_reg * sizeof(struct dci_pkt_req_tracking_tbl), GFP_KERNEL); if (driver->req_tracking_tbl == NULL) goto err; } if (driver->apps_dci_buf == NULL) { driver->apps_dci_buf = kzalloc(APPS_BUF_SIZE, GFP_KERNEL); if (driver->apps_dci_buf == NULL) goto err; } INIT_LIST_HEAD(&driver->dci_client_list); INIT_LIST_HEAD(&driver->dci_req_list); driver->diag_dci_wq = create_singlethread_workqueue("diag_dci_wq"); INIT_WORK(&dci_data_drain_work, dci_data_drain_work_fn); Loading @@ -1549,7 +1604,6 @@ int diag_dci_init(void) return DIAG_DCI_NO_ERROR; err: pr_err("diag: Could not initialize diag DCI buffers"); kfree(driver->req_tracking_tbl); kfree(driver->apps_dci_buf); for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) diag_smd_destructor(&driver->smd_dci[i]); Loading Loading @@ -1582,7 +1636,6 @@ void diag_dci_exit(void) platform_driver_unregister(&msm_diag_dci_cmd_driver); } kfree(driver->req_tracking_tbl); kfree(driver->apps_dci_buf); mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); Loading Loading @@ -1843,6 +1896,8 @@ int diag_dci_deinit_client() struct diag_dci_buf_peripheral_t *proc_buf = NULL; struct diag_dci_client_tbl *entry = diag_dci_get_client_entry(); struct diag_dci_buffer_t *buf_entry, *temp; struct list_head *start, *req_temp; struct dci_pkt_req_entry_t *req_entry = NULL; struct diag_smd_info *smd_info = NULL; if (!entry) Loading Loading @@ -1876,6 +1931,15 @@ int diag_dci_deinit_client() return ret; } list_for_each_safe(start, req_temp, &driver->dci_req_list) { req_entry = list_entry(start, struct dci_pkt_req_entry_t, track); if (req_entry->pid == current->tgid) { list_del(&req_entry->track); kfree(req_entry); } } /* Clean up any buffer that is pending write */ mutex_lock(&entry->write_buf_mutex); list_for_each_entry_safe(buf_entry, temp, &entry->list_write_buf, Loading
drivers/char/diag/diag_dci.h +5 −4 Original line number Diff line number Diff line Loading @@ -49,17 +49,20 @@ #define DCI_MAX_LOG_CODES 16 #define DCI_MAX_ITEMS_PER_LOG_CODE 512 #define MIN_DELAYED_RSP_LEN 12 extern unsigned int dci_max_reg; extern unsigned int dci_max_clients; extern unsigned char dci_cumulative_log_mask[DCI_LOG_MASK_SIZE]; extern unsigned char dci_cumulative_event_mask[DCI_EVENT_MASK_SIZE]; extern struct mutex dci_health_mutex; struct dci_pkt_req_tracking_tbl { struct dci_pkt_req_entry_t { int pid; int uid; int tag; }; struct list_head track; } __packed; struct diag_dci_reg_tbl_t { uint32_t client_id; Loading Loading @@ -160,8 +163,6 @@ void diag_process_apps_dci_read_data(int data_type, void *buf, int recd_bytes); int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf, int recd_bytes); int diag_process_dci_transaction(unsigned char *buf, int len); int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf, int len, int index); void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf, int len); struct diag_dci_client_tbl *diag_dci_get_client_entry(void); Loading
drivers/char/diag/diagchar.h +1 −1 Original line number Diff line number Diff line Loading @@ -314,7 +314,7 @@ struct diagchar_dev { /* Whether or not the peripheral supports STM */ int peripheral_supports_stm[NUM_SMD_CONTROL_CHANNELS]; /* DCI related variables */ struct dci_pkt_req_tracking_tbl *req_tracking_tbl; struct list_head dci_req_list; struct list_head dci_client_list; int dci_tag; int dci_client_id; Loading