Merge "diag: Fix possible use-after-free issue for mdlog session info"
This commit is contained in:
commit
a7e3f3f2de
9 changed files with 328 additions and 190 deletions
|
@ -1,4 +1,4 @@
|
|||
/* 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
|
||||
|
@ -537,8 +537,7 @@ static void diag_send_feature_mask_update(uint8_t peripheral)
|
|||
}
|
||||
|
||||
static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -546,23 +545,30 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
|
|||
struct diag_msg_ssid_query_t rsp;
|
||||
struct diag_ssid_range_t ssid_range;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
mask_info = (!info) ? &msg_mask : info->msg_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
!mask_info) {
|
||||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!diag_apps_responds())
|
||||
if (!diag_apps_responds()) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&driver->msg_mask_lock);
|
||||
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
|
||||
rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
|
||||
|
@ -584,12 +590,12 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
|
|||
write_len += sizeof(ssid_range);
|
||||
}
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return write_len;
|
||||
}
|
||||
|
||||
static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i = 0;
|
||||
int write_len = 0;
|
||||
|
@ -642,8 +648,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -652,6 +657,10 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_build_mask_req_t *req = NULL;
|
||||
struct diag_msg_build_mask_t rsp;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &msg_mask : info->msg_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -659,15 +668,19 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!diag_apps_responds())
|
||||
if (!diag_apps_responds()) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->msg_mask_lock);
|
||||
req = (struct diag_build_mask_req_t *)src_buf;
|
||||
|
@ -682,6 +695,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
|
||||
__func__, mask->ptr);
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
|
||||
|
@ -701,12 +715,12 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
|
|||
memcpy(dest_buf, &rsp, sizeof(rsp));
|
||||
write_len += sizeof(rsp);
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return write_len;
|
||||
}
|
||||
|
||||
static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -720,6 +734,10 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_msg_mask_t *mask_next = NULL;
|
||||
uint32_t *temp = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &msg_mask : info->msg_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -727,11 +745,13 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -744,6 +764,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
|||
__func__, mask->ptr);
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
|
||||
|
@ -786,6 +807,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
|||
mutex_unlock(&mask->lock);
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mask->ptr = temp;
|
||||
|
@ -806,6 +828,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(MSG_MASKS_TYPE);
|
||||
|
||||
|
@ -839,8 +862,7 @@ end:
|
|||
}
|
||||
|
||||
static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -849,6 +871,10 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_msg_config_rsp_t *req = NULL;
|
||||
struct diag_msg_mask_t *mask = NULL;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &msg_mask : info->msg_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -856,11 +882,13 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -875,6 +903,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
|||
__func__, mask->ptr);
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
|
||||
|
@ -887,7 +916,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
mutex_unlock(&driver->msg_mask_lock);
|
||||
mutex_unlock(&mask_info->lock);
|
||||
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(MSG_MASKS_TYPE);
|
||||
|
||||
|
@ -915,8 +944,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int write_len = 0;
|
||||
uint32_t mask_size;
|
||||
|
@ -951,8 +979,7 @@ static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -961,18 +988,23 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_event_mask_config_t rsp;
|
||||
struct diag_event_mask_config_t *req;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
mask_info = (!info) ? &event_mask : info->event_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
!mask_info) {
|
||||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
req = (struct diag_event_mask_config_t *)src_buf;
|
||||
|
@ -980,6 +1012,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
|
|||
if (mask_len <= 0 || mask_len > event_mask.mask_len) {
|
||||
pr_err("diag: In %s, invalid event mask len: %d\n", __func__,
|
||||
mask_len);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -987,6 +1020,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
|
|||
memcpy(mask_info->ptr, src_buf + header_len, mask_len);
|
||||
mask_info->status = DIAG_CTRL_MASK_VALID;
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(EVENT_MASKS_TYPE);
|
||||
|
||||
|
@ -1015,26 +1049,30 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
uint8_t toggle = 0;
|
||||
struct diag_event_report_t header;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
mask_info = (!info) ? &event_mask : info->event_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
!mask_info) {
|
||||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1048,6 +1086,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
|
|||
memset(mask_info->ptr, 0, mask_info->mask_len);
|
||||
}
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(EVENT_MASKS_TYPE);
|
||||
|
||||
|
@ -1071,8 +1110,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int status = LOG_STATUS_INVALID;
|
||||
|
@ -1085,6 +1123,10 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_log_config_req_t *req;
|
||||
struct diag_log_config_rsp_t rsp;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &log_mask : info->log_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -1092,16 +1134,20 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!diag_apps_responds())
|
||||
if (!diag_apps_responds()) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
req = (struct diag_log_config_req_t *)src_buf;
|
||||
read_len += req_header_len;
|
||||
|
@ -1121,6 +1167,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
|
|||
if (!log_item->ptr) {
|
||||
pr_err("diag: Invalid input in %s, mask: %pK\n",
|
||||
__func__, log_item);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
|
||||
|
@ -1162,28 +1209,27 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
|
|||
rsp.status = status;
|
||||
memcpy(dest_buf, &rsp, rsp_header_len);
|
||||
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return write_len;
|
||||
}
|
||||
|
||||
static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
struct diag_log_config_rsp_t rsp;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_log_mask_t *mask = (struct diag_log_mask_t *)log_mask.ptr;
|
||||
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (!diag_apps_responds())
|
||||
return 0;
|
||||
|
||||
mask_info = (!info) ? &log_mask : info->log_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
!mask_info) {
|
||||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
|
||||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1252,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,
|
|||
|
||||
static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
int pid)
|
||||
{
|
||||
int i;
|
||||
int write_len = 0;
|
||||
|
@ -1221,6 +1267,10 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
|
|||
struct diag_log_mask_t *mask = NULL;
|
||||
unsigned char *temp_buf = NULL;
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &log_mask : info->log_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -1228,11 +1278,13 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1242,6 +1294,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
|
|||
if (!mask->ptr) {
|
||||
pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
|
||||
__func__, mask->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (req->equip_id >= MAX_EQUIP_ID) {
|
||||
|
@ -1304,6 +1357,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
|
|||
break;
|
||||
}
|
||||
mutex_unlock(&mask_info->lock);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(LOG_MASKS_TYPE);
|
||||
|
||||
|
@ -1344,14 +1398,16 @@ end:
|
|||
}
|
||||
|
||||
static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info)
|
||||
unsigned char *dest_buf, int dest_len, int pid)
|
||||
{
|
||||
struct diag_mask_info *mask_info = NULL;
|
||||
struct diag_log_mask_t *mask = NULL;
|
||||
struct diag_log_config_rsp_t header;
|
||||
int write_len = 0;
|
||||
int i;
|
||||
int write_len = 0, i;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
|
||||
mask_info = (!info) ? &log_mask : info->log_mask;
|
||||
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
|
||||
|
@ -1359,17 +1415,20 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
|
|||
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
|
||||
__func__, src_buf, src_len, dest_buf, dest_len,
|
||||
mask_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!mask_info->ptr) {
|
||||
pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
|
||||
__func__, mask_info->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
mask = (struct diag_log_mask_t *)mask_info->ptr;
|
||||
if (!mask->ptr) {
|
||||
pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
|
||||
__func__, mask->ptr);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
|
||||
|
@ -1378,6 +1437,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
|
|||
mutex_unlock(&mask->lock);
|
||||
}
|
||||
mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (diag_check_update(APPS_DATA))
|
||||
diag_update_userspace_clients(LOG_MASKS_TYPE);
|
||||
|
||||
|
@ -2109,14 +2169,12 @@ void diag_send_updates_peripheral(uint8_t peripheral)
|
|||
&driver->buffering_mode[peripheral]);
|
||||
}
|
||||
|
||||
int diag_process_apps_masks(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int diag_process_apps_masks(unsigned char *buf, int len, int pid)
|
||||
{
|
||||
int size = 0;
|
||||
int sub_cmd = 0;
|
||||
int (*hdlr)(unsigned char *src_buf, int src_len,
|
||||
unsigned char *dest_buf, int dest_len,
|
||||
struct diag_md_session_t *info) = NULL;
|
||||
unsigned char *dest_buf, int dest_len, int pid) = NULL;
|
||||
|
||||
if (!buf || len <= 0)
|
||||
return -EINVAL;
|
||||
|
@ -2166,7 +2224,7 @@ int diag_process_apps_masks(unsigned char *buf, int len,
|
|||
|
||||
if (hdlr)
|
||||
size = hdlr(buf, len, driver->apps_rsp_buf,
|
||||
DIAG_MAX_RSP_SIZE, info);
|
||||
DIAG_MAX_RSP_SIZE, pid);
|
||||
|
||||
return (size > 0) ? size : 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2015, 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
|
||||
|
@ -167,8 +167,7 @@ int diag_event_mask_copy(struct diag_mask_info *dest,
|
|||
void diag_log_mask_free(struct diag_mask_info *mask_info);
|
||||
void diag_msg_mask_free(struct diag_mask_info *mask_info);
|
||||
void diag_event_mask_free(struct diag_mask_info *mask_info);
|
||||
int diag_process_apps_masks(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info);
|
||||
int diag_process_apps_masks(unsigned char *buf, int len, int pid);
|
||||
void diag_send_updates_peripheral(uint8_t peripheral);
|
||||
|
||||
extern int diag_create_msg_mask_table_entry(struct diag_msg_mask_t *msg_mask,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-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
|
||||
|
@ -131,7 +131,7 @@ void diag_md_close_all()
|
|||
|
||||
int diag_md_write(int id, unsigned char *buf, int len, int ctx)
|
||||
{
|
||||
int i;
|
||||
int i, pid = 0;
|
||||
uint8_t found = 0;
|
||||
unsigned long flags;
|
||||
struct diag_md_info *ch = NULL;
|
||||
|
@ -149,10 +149,14 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
|
|||
if (peripheral < 0)
|
||||
return -EINVAL;
|
||||
|
||||
session_info =
|
||||
diag_md_session_get_peripheral(peripheral);
|
||||
if (!session_info)
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_peripheral(peripheral);
|
||||
if (!session_info) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EIO;
|
||||
}
|
||||
pid = session_info->pid;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
|
||||
ch = &diag_md[id];
|
||||
if (!ch)
|
||||
|
@ -195,8 +199,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
|
|||
|
||||
found = 0;
|
||||
for (i = 0; i < driver->num_clients && !found; i++) {
|
||||
if ((driver->client_map[i].pid !=
|
||||
session_info->pid) ||
|
||||
if ((driver->client_map[i].pid != pid) ||
|
||||
(driver->client_map[i].pid == 0))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-2016, 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
|
||||
|
@ -221,7 +221,7 @@ static void usb_disconnect(struct diag_usb_info *ch)
|
|||
|
||||
if (!atomic_read(&ch->connected) &&
|
||||
driver->usb_connected && diag_mask_param())
|
||||
diag_clear_masks(NULL);
|
||||
diag_clear_masks(0);
|
||||
|
||||
if (ch && ch->ops && ch->ops->close)
|
||||
ch->ops->close(ch->ctxt, DIAG_USB_MODE);
|
||||
|
|
|
@ -676,7 +676,7 @@ void diag_cmd_remove_reg_by_pid(int pid);
|
|||
void diag_cmd_remove_reg_by_proc(int proc);
|
||||
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
|
||||
int diag_mask_param(void);
|
||||
void diag_clear_masks(struct diag_md_session_t *info);
|
||||
void diag_clear_masks(int pid);
|
||||
uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask);
|
||||
|
||||
void diag_record_stats(int type, int flag);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* 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
|
||||
|
@ -170,7 +170,7 @@ uint16_t diag_debug_mask;
|
|||
void *diag_ipc_log;
|
||||
#endif
|
||||
|
||||
static void diag_md_session_close(struct diag_md_session_t *session_info);
|
||||
static void diag_md_session_close(int pid);
|
||||
|
||||
/*
|
||||
* Returns the next delayed rsp id. If wrapping is enabled,
|
||||
|
@ -209,6 +209,16 @@ do { \
|
|||
ret += length; \
|
||||
} while (0)
|
||||
|
||||
#define COPY_USER_SPACE_OR_ERR(buf, data, length) \
|
||||
do { \
|
||||
if ((count < ret+length) || (copy_to_user(buf, \
|
||||
(void *)&data, length))) { \
|
||||
ret = -EFAULT; \
|
||||
break; \
|
||||
} \
|
||||
ret += length; \
|
||||
} while (0)
|
||||
|
||||
static void drain_timer_func(unsigned long data)
|
||||
{
|
||||
queue_work(driver->diag_wq , &(driver->diag_drain_work));
|
||||
|
@ -247,12 +257,13 @@ void diag_drain_work_fn(struct work_struct *work)
|
|||
|
||||
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);
|
||||
if (!hdlc_disabled)
|
||||
diag_drain_apps_data(&hdlc_data);
|
||||
else
|
||||
|
@ -438,7 +449,7 @@ int diag_mask_param(void)
|
|||
{
|
||||
return diag_mask_clear_param;
|
||||
}
|
||||
void diag_clear_masks(struct diag_md_session_t *info)
|
||||
void diag_clear_masks(int pid)
|
||||
{
|
||||
int ret;
|
||||
char cmd_disable_log_mask[] = { 0x73, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
@ -447,14 +458,14 @@ void diag_clear_masks(struct diag_md_session_t *info)
|
|||
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag: %s: masks clear request upon %s\n", __func__,
|
||||
((info) ? "ODL exit" : "USB Disconnection"));
|
||||
((pid) ? "ODL exit" : "USB Disconnection"));
|
||||
|
||||
ret = diag_process_apps_masks(cmd_disable_log_mask,
|
||||
sizeof(cmd_disable_log_mask), info);
|
||||
sizeof(cmd_disable_log_mask), pid);
|
||||
ret = diag_process_apps_masks(cmd_disable_msg_mask,
|
||||
sizeof(cmd_disable_msg_mask), info);
|
||||
sizeof(cmd_disable_msg_mask), pid);
|
||||
ret = diag_process_apps_masks(cmd_disable_event_mask,
|
||||
sizeof(cmd_disable_event_mask), info);
|
||||
sizeof(cmd_disable_event_mask), pid);
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag:%s: masks cleared successfully\n", __func__);
|
||||
}
|
||||
|
@ -467,12 +478,17 @@ static void diag_close_logging_process(const int pid)
|
|||
struct diag_md_session_t *session_info = NULL;
|
||||
struct diag_logging_mode_param_t params;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(pid);
|
||||
if (!session_info)
|
||||
if (!session_info) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return;
|
||||
}
|
||||
session_mask = session_info->peripheral_mask;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
|
||||
if (diag_mask_clear_param)
|
||||
diag_clear_masks(session_info);
|
||||
diag_clear_masks(pid);
|
||||
|
||||
mutex_lock(&driver->diag_maskclear_mutex);
|
||||
driver->mask_clear = 1;
|
||||
|
@ -480,9 +496,6 @@ static void diag_close_logging_process(const int pid)
|
|||
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
|
||||
session_mask = session_info->peripheral_mask;
|
||||
diag_md_session_close(session_info);
|
||||
|
||||
p_mask =
|
||||
diag_translate_kernel_to_user_mask(session_mask);
|
||||
|
||||
|
@ -506,7 +519,9 @@ static void diag_close_logging_process(const int pid)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
diag_md_session_close(pid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
diag_switch_logging(¶ms);
|
||||
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
|
@ -1040,11 +1055,13 @@ 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);
|
||||
if (hdlc_disabled) {
|
||||
if (len < 4) {
|
||||
pr_err("diag: In %s, invalid len: %d of non_hdlc pkt",
|
||||
|
@ -1408,15 +1425,16 @@ fail_peripheral:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void diag_md_session_close(struct diag_md_session_t *session_info)
|
||||
static void diag_md_session_close(int pid)
|
||||
{
|
||||
int i;
|
||||
uint8_t found = 0;
|
||||
struct diag_md_session_t *session_info = NULL;
|
||||
|
||||
session_info = diag_md_session_get_pid(pid);
|
||||
if (!session_info)
|
||||
return;
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
for (i = 0; i < NUM_MD_SESSIONS; i++) {
|
||||
if (driver->md_session_map[i] != session_info)
|
||||
continue;
|
||||
|
@ -1442,13 +1460,14 @@ static void diag_md_session_close(struct diag_md_session_t *session_info)
|
|||
driver->md_session_mode = (found) ? DIAG_MD_PERIPHERAL : DIAG_MD_NONE;
|
||||
kfree(session_info);
|
||||
session_info = NULL;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE, "cleared up session\n");
|
||||
}
|
||||
|
||||
struct diag_md_session_t *diag_md_session_get_pid(int pid)
|
||||
{
|
||||
int i;
|
||||
if (pid <= 0)
|
||||
return NULL;
|
||||
for (i = 0; i < NUM_MD_SESSIONS; i++) {
|
||||
if (driver->md_session_map[i] &&
|
||||
driver->md_session_map[i]->pid == pid)
|
||||
|
@ -1464,10 +1483,12 @@ struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral)
|
|||
return driver->md_session_map[peripheral];
|
||||
}
|
||||
|
||||
static int diag_md_peripheral_switch(struct diag_md_session_t *session_info,
|
||||
static int diag_md_peripheral_switch(int pid,
|
||||
int peripheral_mask, int req_mode) {
|
||||
int i, bit = 0;
|
||||
struct diag_md_session_t *session_info = NULL;
|
||||
|
||||
session_info = diag_md_session_get_pid(pid);
|
||||
if (!session_info)
|
||||
return -EINVAL;
|
||||
if (req_mode != DIAG_USB_MODE || req_mode != DIAG_MEMORY_DEVICE_MODE)
|
||||
|
@ -1477,25 +1498,20 @@ static int diag_md_peripheral_switch(struct diag_md_session_t *session_info,
|
|||
* check that md_session_map for i == session_info,
|
||||
* if not then race condition occurred and bail
|
||||
*/
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
for (i = 0; i < NUM_MD_SESSIONS; i++) {
|
||||
bit = MD_PERIPHERAL_MASK(i) & peripheral_mask;
|
||||
if (!bit)
|
||||
continue;
|
||||
if (req_mode == DIAG_USB_MODE) {
|
||||
if (driver->md_session_map[i] != session_info) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (driver->md_session_map[i] != session_info)
|
||||
return -EINVAL;
|
||||
}
|
||||
driver->md_session_map[i] = NULL;
|
||||
driver->md_session_mask &= ~bit;
|
||||
session_info->peripheral_mask &= ~bit;
|
||||
|
||||
} else {
|
||||
if (driver->md_session_map[i] != NULL) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (driver->md_session_map[i] != NULL)
|
||||
return -EINVAL;
|
||||
}
|
||||
driver->md_session_map[i] = session_info;
|
||||
driver->md_session_mask |= bit;
|
||||
session_info->peripheral_mask |= bit;
|
||||
|
@ -1504,7 +1520,6 @@ static int diag_md_peripheral_switch(struct diag_md_session_t *session_info,
|
|||
}
|
||||
|
||||
driver->md_session_mode = DIAG_MD_PERIPHERAL;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE, "Changed Peripherals:0x%x to mode:%d\n",
|
||||
peripheral_mask, req_mode);
|
||||
}
|
||||
|
@ -1513,7 +1528,7 @@ static int diag_md_session_check(int curr_mode, int req_mode,
|
|||
const struct diag_logging_mode_param_t *param,
|
||||
uint8_t *change_mode)
|
||||
{
|
||||
int i, bit = 0, err = 0;
|
||||
int i, bit = 0, err = 0, peripheral_mask = 0;
|
||||
int change_mask = 0;
|
||||
struct diag_md_session_t *session_info = NULL;
|
||||
|
||||
|
@ -1537,12 +1552,13 @@ static int diag_md_session_check(int curr_mode, int req_mode,
|
|||
if (req_mode == DIAG_USB_MODE) {
|
||||
if (curr_mode == DIAG_USB_MODE)
|
||||
return 0;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
if (driver->md_session_mode == DIAG_MD_NONE
|
||||
&& driver->md_session_mask == 0 && driver->logging_mask) {
|
||||
*change_mode = 1;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* curr_mode is either DIAG_MULTI_MODE or DIAG_MD_MODE
|
||||
* Check if requested peripherals are already in usb mode
|
||||
|
@ -1554,8 +1570,10 @@ static int diag_md_session_check(int curr_mode, int req_mode,
|
|||
if (bit & driver->logging_mask)
|
||||
change_mask |= bit;
|
||||
}
|
||||
if (!change_mask)
|
||||
if (!change_mask) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change is needed. Check if this md_session has set all the
|
||||
|
@ -1564,29 +1582,29 @@ static int diag_md_session_check(int curr_mode, int req_mode,
|
|||
* If this session owns all the requested peripherals, then
|
||||
* call function to switch the modes/masks for the md_session
|
||||
*/
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
|
||||
if (!session_info) {
|
||||
*change_mode = 1;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return 0;
|
||||
}
|
||||
if ((change_mask & session_info->peripheral_mask)
|
||||
peripheral_mask = session_info->peripheral_mask;
|
||||
if ((change_mask & peripheral_mask)
|
||||
!= change_mask) {
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"Another MD Session owns a requested peripheral\n");
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
*change_mode = 1;
|
||||
|
||||
/* If all peripherals are being set to USB Mode, call close */
|
||||
if (~change_mask & session_info->peripheral_mask) {
|
||||
err = diag_md_peripheral_switch(session_info,
|
||||
if (~change_mask & peripheral_mask) {
|
||||
err = diag_md_peripheral_switch(current->tgid,
|
||||
change_mask, DIAG_USB_MODE);
|
||||
} else
|
||||
diag_md_session_close(session_info);
|
||||
|
||||
diag_md_session_close(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return err;
|
||||
|
||||
} else if (req_mode == DIAG_MEMORY_DEVICE_MODE) {
|
||||
|
@ -1595,21 +1613,23 @@ static int diag_md_session_check(int curr_mode, int req_mode,
|
|||
* been set. Check that requested peripherals already set are
|
||||
* owned by this md session
|
||||
*/
|
||||
change_mask = driver->md_session_mask & param->peripheral_mask;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
change_mask = driver->md_session_mask & param->peripheral_mask;
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
|
||||
if (session_info) {
|
||||
if ((session_info->peripheral_mask & change_mask)
|
||||
!= change_mask) {
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"Another MD Session owns a requested peripheral\n");
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
err = diag_md_peripheral_switch(session_info,
|
||||
err = diag_md_peripheral_switch(current->tgid,
|
||||
change_mask, DIAG_USB_MODE);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
} else {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (change_mask) {
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"Another MD Session owns a requested peripheral\n");
|
||||
|
@ -2065,19 +2085,17 @@ static int diag_ioctl_hdlc_toggle(unsigned long ioarg)
|
|||
{
|
||||
uint8_t hdlc_support;
|
||||
struct diag_md_session_t *session_info = NULL;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
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);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
if (session_info)
|
||||
session_info->hdlc_disabled = hdlc_support;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
} else
|
||||
else
|
||||
driver->hdlc_disabled = hdlc_support;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
mutex_unlock(&driver->hdlc_disable_mutex);
|
||||
diag_update_md_clients(HDLC_SUPPORT_TYPE);
|
||||
|
||||
|
@ -2789,7 +2807,6 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
|
|||
int remote_proc = 0;
|
||||
const int mempool = POOL_TYPE_COPY;
|
||||
unsigned char *user_space_data = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
if (!buf || len <= 0 || len > CALLBACK_BUF_SIZE) {
|
||||
pr_err_ratelimited("diag: In %s, invalid buf %pK len: %d\n",
|
||||
|
@ -2840,13 +2857,11 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
|
|||
} else {
|
||||
wait_event_interruptible(driver->wait_q,
|
||||
(driver->in_busy_pktdata == 0));
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
ret = diag_process_apps_pkt(user_space_data, len, info);
|
||||
ret = diag_process_apps_pkt(user_space_data, len,
|
||||
current->tgid);
|
||||
if (ret == 1)
|
||||
diag_send_error_rsp((void *)(user_space_data), len,
|
||||
info);
|
||||
current->tgid);
|
||||
}
|
||||
fail:
|
||||
diagmem_free(driver, user_space_data, mempool);
|
||||
|
@ -2912,24 +2927,25 @@ static int diag_user_process_userspace_data(const char __user *buf, int len)
|
|||
if (!remote_proc) {
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (!session_info) {
|
||||
pr_err("diag:In %s request came from invalid md session pid:%d",
|
||||
__func__, current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (session_info)
|
||||
hdlc_disabled = session_info->hdlc_disabled;
|
||||
else
|
||||
hdlc_disabled = driver->hdlc_disabled;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (!hdlc_disabled)
|
||||
diag_process_hdlc_pkt((void *)
|
||||
(driver->user_space_data_buf),
|
||||
len, session_info);
|
||||
len, current->tgid);
|
||||
else
|
||||
diag_process_non_hdlc_pkt((char *)
|
||||
(driver->user_space_data_buf),
|
||||
len, session_info);
|
||||
len, current->tgid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3006,11 +3022,13 @@ 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);
|
||||
if (hdlc_disabled)
|
||||
ret = diag_process_apps_data_non_hdlc(user_space_data, len,
|
||||
pkt_type);
|
||||
|
@ -3079,9 +3097,9 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
|
|||
ret += sizeof(int);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
exit_stat = diag_md_copy_to_user(buf, &ret, count,
|
||||
session_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
} else if (driver->data_ready[index] & USER_SPACE_DATA_TYPE) {
|
||||
/* In case, the thread wakes up and the logging mode is
|
||||
|
@ -3097,11 +3115,16 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
|
|||
COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(current->tgid);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (session_info)
|
||||
COPY_USER_SPACE_OR_EXIT(buf+4,
|
||||
if (session_info) {
|
||||
COPY_USER_SPACE_OR_ERR(buf+4,
|
||||
session_info->hdlc_disabled,
|
||||
sizeof(uint8_t));
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -3119,10 +3142,16 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
|
|||
if (driver->data_ready[index] & MSG_MASKS_TYPE) {
|
||||
/*Copy the type of data being passed*/
|
||||
data_type = driver->data_ready[index] & MSG_MASKS_TYPE;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_peripheral(APPS_DATA);
|
||||
COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
|
||||
COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
write_len = diag_copy_to_user_msg_mask(buf + ret, count,
|
||||
session_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (write_len > 0)
|
||||
ret += write_len;
|
||||
driver->data_ready[index] ^= MSG_MASKS_TYPE;
|
||||
|
@ -3133,18 +3162,32 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
|
|||
if (driver->data_ready[index] & EVENT_MASKS_TYPE) {
|
||||
/*Copy the type of data being passed*/
|
||||
data_type = driver->data_ready[index] & EVENT_MASKS_TYPE;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_peripheral(APPS_DATA);
|
||||
COPY_USER_SPACE_OR_EXIT(buf, data_type, 4);
|
||||
COPY_USER_SPACE_OR_ERR(buf, data_type, 4);
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
if (session_info && session_info->event_mask &&
|
||||
session_info->event_mask->ptr) {
|
||||
COPY_USER_SPACE_OR_EXIT(buf + sizeof(int),
|
||||
COPY_USER_SPACE_OR_ERR(buf + sizeof(int),
|
||||
*(session_info->event_mask->ptr),
|
||||
session_info->event_mask->mask_len);
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
COPY_USER_SPACE_OR_EXIT(buf + sizeof(int),
|
||||
COPY_USER_SPACE_OR_ERR(buf + sizeof(int),
|
||||
*(event_mask.ptr),
|
||||
event_mask.mask_len);
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
driver->data_ready[index] ^= EVENT_MASKS_TYPE;
|
||||
atomic_dec(&driver->data_ready_notif[index]);
|
||||
goto exit;
|
||||
|
@ -3153,10 +3196,16 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
|
|||
if (driver->data_ready[index] & LOG_MASKS_TYPE) {
|
||||
/*Copy the type of data being passed*/
|
||||
data_type = driver->data_ready[index] & LOG_MASKS_TYPE;
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_peripheral(APPS_DATA);
|
||||
COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
|
||||
COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
|
||||
if (ret == -EFAULT) {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
goto exit;
|
||||
}
|
||||
write_len = diag_copy_to_user_log_mask(buf + ret, count,
|
||||
session_info);
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (write_len > 0)
|
||||
ret += write_len;
|
||||
driver->data_ready[index] ^= LOG_MASKS_TYPE;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* 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
|
||||
|
@ -242,7 +242,7 @@ void chk_logging_wakeup(void)
|
|||
}
|
||||
|
||||
static void pack_rsp_and_send(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int pid)
|
||||
{
|
||||
int err;
|
||||
int retry_count = 0, i, rsp_ctxt;
|
||||
|
@ -250,6 +250,7 @@ static void pack_rsp_and_send(unsigned char *buf, int len,
|
|||
unsigned long flags;
|
||||
unsigned char *rsp_ptr = driver->encoded_rsp_buf;
|
||||
struct diag_pkt_frame_t header;
|
||||
struct diag_md_session_t *session_info = NULL, *info = NULL;
|
||||
|
||||
if (!rsp_ptr || !buf)
|
||||
return;
|
||||
|
@ -260,6 +261,11 @@ static void pack_rsp_and_send(unsigned char *buf, int len,
|
|||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(pid);
|
||||
info = (session_info) ? session_info :
|
||||
diag_md_session_get_peripheral(APPS_DATA);
|
||||
|
||||
if (info && info->peripheral_mask) {
|
||||
if (info->peripheral_mask == DIAG_CON_ALL ||
|
||||
(info->peripheral_mask & (1 << APPS_DATA)) ||
|
||||
|
@ -274,6 +280,7 @@ static void pack_rsp_and_send(unsigned char *buf, int len,
|
|||
}
|
||||
} else
|
||||
rsp_ctxt = driver->rsp_buf_ctxt;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
|
||||
/*
|
||||
* Keep trying till we get the buffer back. It should probably
|
||||
|
@ -297,8 +304,11 @@ static void pack_rsp_and_send(unsigned char *buf, int len,
|
|||
* draining responses when we are in Memory Device Mode.
|
||||
*/
|
||||
if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE ||
|
||||
driver->logging_mode == DIAG_MULTI_MODE)
|
||||
driver->logging_mode == DIAG_MULTI_MODE) {
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
chk_logging_wakeup();
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
}
|
||||
}
|
||||
if (driver->rsp_buf_busy) {
|
||||
pr_err("diag: unable to get hold of response buffer\n");
|
||||
|
@ -327,13 +337,14 @@ static void pack_rsp_and_send(unsigned char *buf, int len,
|
|||
}
|
||||
|
||||
static void encode_rsp_and_send(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int pid)
|
||||
{
|
||||
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
|
||||
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
|
||||
unsigned char *rsp_ptr = driver->encoded_rsp_buf;
|
||||
int err, i, rsp_ctxt, retry_count = 0;
|
||||
unsigned long flags;
|
||||
struct diag_md_session_t *session_info = NULL, *info = NULL;
|
||||
|
||||
if (!rsp_ptr || !buf)
|
||||
return;
|
||||
|
@ -344,6 +355,11 @@ static void encode_rsp_and_send(unsigned char *buf, int len,
|
|||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
session_info = diag_md_session_get_pid(pid);
|
||||
info = (session_info) ? session_info :
|
||||
diag_md_session_get_peripheral(APPS_DATA);
|
||||
|
||||
if (info && info->peripheral_mask) {
|
||||
if (info->peripheral_mask == DIAG_CON_ALL ||
|
||||
(info->peripheral_mask & (1 << APPS_DATA)) ||
|
||||
|
@ -358,7 +374,7 @@ static void encode_rsp_and_send(unsigned char *buf, int len,
|
|||
}
|
||||
} else
|
||||
rsp_ctxt = driver->rsp_buf_ctxt;
|
||||
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
/*
|
||||
* Keep trying till we get the buffer back. It should probably
|
||||
* take one or two iterations. When this loops till UINT_MAX, it
|
||||
|
@ -381,8 +397,11 @@ static void encode_rsp_and_send(unsigned char *buf, int len,
|
|||
* draining responses when we are in Memory Device Mode.
|
||||
*/
|
||||
if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE ||
|
||||
driver->logging_mode == DIAG_MULTI_MODE)
|
||||
driver->logging_mode == DIAG_MULTI_MODE) {
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
chk_logging_wakeup();
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
}
|
||||
}
|
||||
|
||||
if (driver->rsp_buf_busy) {
|
||||
|
@ -413,22 +432,23 @@ static void encode_rsp_and_send(unsigned char *buf, int len,
|
|||
memset(buf, '\0', DIAG_MAX_RSP_SIZE);
|
||||
}
|
||||
|
||||
void diag_send_rsp(unsigned char *buf, int len, struct diag_md_session_t *info)
|
||||
static void diag_send_rsp(unsigned char *buf, int len, int pid)
|
||||
{
|
||||
struct diag_md_session_t *session_info = NULL;
|
||||
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 :
|
||||
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);
|
||||
if (hdlc_disabled)
|
||||
pack_rsp_and_send(buf, len, session_info);
|
||||
pack_rsp_and_send(buf, len, pid);
|
||||
else
|
||||
encode_rsp_and_send(buf, len, session_info);
|
||||
encode_rsp_and_send(buf, len, pid);
|
||||
}
|
||||
|
||||
void diag_update_pkt_buffer(unsigned char *buf, uint32_t len, int type)
|
||||
|
@ -494,6 +514,7 @@ void diag_update_md_clients(unsigned int type)
|
|||
int i, j;
|
||||
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
for (i = 0; i < NUM_MD_SESSIONS; i++) {
|
||||
if (driver->md_session_map[i] != NULL)
|
||||
for (j = 0; j < driver->num_clients; j++) {
|
||||
|
@ -507,6 +528,7 @@ void diag_update_md_clients(unsigned int type)
|
|||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
wake_up_interruptible(&driver->wait_q);
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
}
|
||||
|
@ -905,7 +927,7 @@ static int diag_cmd_disable_hdlc(unsigned char *src_buf, int src_len,
|
|||
}
|
||||
|
||||
void diag_send_error_rsp(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int pid)
|
||||
{
|
||||
/* -1 to accomodate the first byte 0x13 */
|
||||
if (len > (DIAG_MAX_RSP_SIZE - 1)) {
|
||||
|
@ -915,27 +937,27 @@ void diag_send_error_rsp(unsigned char *buf, int len,
|
|||
|
||||
*(uint8_t *)driver->apps_rsp_buf = DIAG_CMD_ERROR;
|
||||
memcpy((driver->apps_rsp_buf + sizeof(uint8_t)), buf, len);
|
||||
diag_send_rsp(driver->apps_rsp_buf, len + 1, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, len + 1, pid);
|
||||
}
|
||||
|
||||
int diag_process_apps_pkt(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
|
||||
{
|
||||
int i;
|
||||
int i, p_mask = 0;
|
||||
int mask_ret;
|
||||
int write_len = 0;
|
||||
unsigned char *temp = NULL;
|
||||
struct diag_cmd_reg_entry_t entry;
|
||||
struct diag_cmd_reg_entry_t *temp_entry = NULL;
|
||||
struct diag_cmd_reg_t *reg_item = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
if (!buf)
|
||||
return -EIO;
|
||||
|
||||
/* Check if the command is a supported mask command */
|
||||
mask_ret = diag_process_apps_masks(buf, len, info);
|
||||
mask_ret = diag_process_apps_masks(buf, len, pid);
|
||||
if (mask_ret > 0) {
|
||||
diag_send_rsp(driver->apps_rsp_buf, mask_ret, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, mask_ret, pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -957,7 +979,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, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -966,14 +988,18 @@ 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);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
if (info) {
|
||||
if (MD_PERIPHERAL_MASK(reg_item->proc) &
|
||||
info->peripheral_mask)
|
||||
p_mask = info->peripheral_mask;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (MD_PERIPHERAL_MASK(reg_item->proc) & p_mask)
|
||||
write_len = diag_send_data(reg_item, buf, len);
|
||||
} else {
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
if (MD_PERIPHERAL_MASK(reg_item->proc) &
|
||||
driver->logging_mask)
|
||||
diag_send_error_rsp(buf, len, info);
|
||||
diag_send_error_rsp(buf, len, pid);
|
||||
else
|
||||
write_len = diag_send_data(reg_item, buf, len);
|
||||
}
|
||||
|
@ -989,13 +1015,13 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
for (i = 0; i < 4; i++)
|
||||
*(driver->apps_rsp_buf+i) = *(buf+i);
|
||||
*(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE;
|
||||
diag_send_rsp(driver->apps_rsp_buf, 8, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 8, pid);
|
||||
return 0;
|
||||
} else if ((*buf == 0x4b) && (*(buf+1) == 0x12) &&
|
||||
(*(uint16_t *)(buf+2) == DIAG_DIAG_STM)) {
|
||||
len = diag_process_stm_cmd(buf, driver->apps_rsp_buf);
|
||||
if (len > 0) {
|
||||
diag_send_rsp(driver->apps_rsp_buf, len, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, len, pid);
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
|
@ -1008,7 +1034,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, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
return 0;
|
||||
}
|
||||
/* Check for time sync switch command */
|
||||
|
@ -1019,14 +1045,14 @@ 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, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
return 0;
|
||||
}
|
||||
/* Check for download command */
|
||||
else if ((chk_apps_master()) && (*buf == 0x3A)) {
|
||||
/* send response back */
|
||||
driver->apps_rsp_buf[0] = *buf;
|
||||
diag_send_rsp(driver->apps_rsp_buf, 1, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 1, pid);
|
||||
msleep(5000);
|
||||
/* call download API */
|
||||
msm_set_restart_mode(RESTART_DLOAD);
|
||||
|
@ -1046,7 +1072,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
for (i = 0; i < 13; i++)
|
||||
driver->apps_rsp_buf[i+3] = 0;
|
||||
|
||||
diag_send_rsp(driver->apps_rsp_buf, 16, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 16, pid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1055,7 +1081,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
(*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
|
||||
memcpy(driver->apps_rsp_buf, buf, 4);
|
||||
driver->apps_rsp_buf[4] = wrap_enabled;
|
||||
diag_send_rsp(driver->apps_rsp_buf, 5, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 5, pid);
|
||||
return 0;
|
||||
}
|
||||
/* Wrap the Delayed Rsp ID */
|
||||
|
@ -1064,7 +1090,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
wrap_enabled = true;
|
||||
memcpy(driver->apps_rsp_buf, buf, 4);
|
||||
driver->apps_rsp_buf[4] = wrap_count;
|
||||
diag_send_rsp(driver->apps_rsp_buf, 6, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 6, pid);
|
||||
return 0;
|
||||
}
|
||||
/* Mobile ID Rsp */
|
||||
|
@ -1075,7 +1101,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, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1095,7 +1121,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
for (i = 0; i < 55; i++)
|
||||
driver->apps_rsp_buf[i] = 0;
|
||||
|
||||
diag_send_rsp(driver->apps_rsp_buf, 55, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 55, pid);
|
||||
return 0;
|
||||
}
|
||||
/* respond to 0x7c command */
|
||||
|
@ -1108,14 +1134,14 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
chk_config_get_id();
|
||||
*(unsigned char *)(driver->apps_rsp_buf + 12) = '\0';
|
||||
*(unsigned char *)(driver->apps_rsp_buf + 13) = '\0';
|
||||
diag_send_rsp(driver->apps_rsp_buf, 14, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, 14, pid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
write_len = diag_cmd_chk_stats(buf, len, driver->apps_rsp_buf,
|
||||
DIAG_MAX_RSP_SIZE);
|
||||
if (write_len > 0) {
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
return 0;
|
||||
}
|
||||
write_len = diag_cmd_disable_hdlc(buf, len, driver->apps_rsp_buf,
|
||||
|
@ -1127,7 +1153,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
* before disabling HDLC encoding on Apps processor.
|
||||
*/
|
||||
mutex_lock(&driver->hdlc_disable_mutex);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, info);
|
||||
diag_send_rsp(driver->apps_rsp_buf, write_len, pid);
|
||||
/*
|
||||
* Set the value of hdlc_disabled after sending the response to
|
||||
* the tools. This is required since the tools is expecting a
|
||||
|
@ -1135,10 +1161,13 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
*/
|
||||
pr_debug("diag: In %s, disabling HDLC encoding\n",
|
||||
__func__);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
if (info)
|
||||
info->hdlc_disabled = 1;
|
||||
else
|
||||
driver->hdlc_disabled = 1;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
diag_update_md_clients(HDLC_SUPPORT_TYPE);
|
||||
mutex_unlock(&driver->hdlc_disable_mutex);
|
||||
return 0;
|
||||
|
@ -1147,13 +1176,12 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
|
|||
|
||||
/* We have now come to the end of the function. */
|
||||
if (chk_apps_only())
|
||||
diag_send_error_rsp(buf, len, info);
|
||||
diag_send_error_rsp(buf, len, pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void diag_process_hdlc_pkt(void *data, unsigned len,
|
||||
struct diag_md_session_t *info)
|
||||
void diag_process_hdlc_pkt(void *data, unsigned int len, int pid)
|
||||
{
|
||||
int err = 0;
|
||||
int ret = 0;
|
||||
|
@ -1213,7 +1241,7 @@ void diag_process_hdlc_pkt(void *data, unsigned len,
|
|||
}
|
||||
|
||||
err = diag_process_apps_pkt(driver->hdlc_buf,
|
||||
driver->hdlc_buf_len, info);
|
||||
driver->hdlc_buf_len, pid);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
} else {
|
||||
|
@ -1230,7 +1258,7 @@ fail:
|
|||
* recovery algorithm. Send an error response if the
|
||||
* packet is not in expected format.
|
||||
*/
|
||||
diag_send_error_rsp(driver->hdlc_buf, driver->hdlc_buf_len, info);
|
||||
diag_send_error_rsp(driver->hdlc_buf, driver->hdlc_buf_len, pid);
|
||||
driver->hdlc_buf_len = 0;
|
||||
end:
|
||||
mutex_unlock(&driver->diag_hdlc_mutex);
|
||||
|
@ -1327,9 +1355,11 @@ static int diagfwd_mux_close(int id, int mode)
|
|||
|
||||
static uint8_t hdlc_reset;
|
||||
|
||||
static void hdlc_reset_timer_start(struct diag_md_session_t *info)
|
||||
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) {
|
||||
hdlc_timer_in_progress = 1;
|
||||
if (info)
|
||||
|
@ -1371,15 +1401,16 @@ void diag_md_hdlc_reset_timer_func(unsigned long pid)
|
|||
}
|
||||
|
||||
static void diag_hdlc_start_recovery(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
int pid)
|
||||
{
|
||||
int i;
|
||||
static uint32_t bad_byte_counter;
|
||||
unsigned char *start_ptr = NULL;
|
||||
struct diag_pkt_frame_t *actual_pkt = NULL;
|
||||
struct diag_md_session_t *info = NULL;
|
||||
|
||||
hdlc_reset = 1;
|
||||
hdlc_reset_timer_start(info);
|
||||
hdlc_reset_timer_start(pid);
|
||||
|
||||
actual_pkt = (struct diag_pkt_frame_t *)buf;
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -1398,10 +1429,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);
|
||||
mutex_lock(&driver->md_session_lock);
|
||||
info = diag_md_session_get_pid(pid);
|
||||
if (info)
|
||||
info->hdlc_disabled = 0;
|
||||
else
|
||||
driver->hdlc_disabled = 0;
|
||||
mutex_unlock(&driver->md_session_lock);
|
||||
mutex_unlock(&driver->hdlc_disable_mutex);
|
||||
diag_update_md_clients(HDLC_SUPPORT_TYPE);
|
||||
|
||||
|
@ -1414,12 +1448,11 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len,
|
|||
mutex_lock(&driver->hdlc_recovery_mutex);
|
||||
driver->incoming_pkt.processing = 0;
|
||||
mutex_unlock(&driver->hdlc_recovery_mutex);
|
||||
diag_process_non_hdlc_pkt(start_ptr, len - i, info);
|
||||
diag_process_non_hdlc_pkt(start_ptr, len - i, pid);
|
||||
}
|
||||
}
|
||||
|
||||
void diag_process_non_hdlc_pkt(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info)
|
||||
void diag_process_non_hdlc_pkt(unsigned char *buf, int len, int pid)
|
||||
{
|
||||
int err = 0;
|
||||
uint16_t pkt_len = 0;
|
||||
|
@ -1475,11 +1508,11 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len,
|
|||
if (*(uint8_t *)(data_ptr + actual_pkt->length) !=
|
||||
CONTROL_CHAR) {
|
||||
mutex_unlock(&driver->hdlc_recovery_mutex);
|
||||
diag_hdlc_start_recovery(buf, len, info);
|
||||
diag_hdlc_start_recovery(buf, len, pid);
|
||||
mutex_lock(&driver->hdlc_recovery_mutex);
|
||||
}
|
||||
err = diag_process_apps_pkt(data_ptr,
|
||||
actual_pkt->length, info);
|
||||
actual_pkt->length, pid);
|
||||
if (err) {
|
||||
pr_err("diag: In %s, unable to process incoming data packet, err: %d\n",
|
||||
__func__, err);
|
||||
|
@ -1501,8 +1534,8 @@ start:
|
|||
pkt_len = actual_pkt->length;
|
||||
|
||||
if (actual_pkt->start != CONTROL_CHAR) {
|
||||
diag_hdlc_start_recovery(buf, len, info);
|
||||
diag_send_error_rsp(buf, len, info);
|
||||
diag_hdlc_start_recovery(buf, len, pid);
|
||||
diag_send_error_rsp(buf, len, pid);
|
||||
goto end;
|
||||
}
|
||||
mutex_lock(&driver->hdlc_recovery_mutex);
|
||||
|
@ -1510,7 +1543,7 @@ start:
|
|||
pr_err("diag: In %s, incoming data is too large for the request buffer %d\n",
|
||||
__func__, pkt_len);
|
||||
mutex_unlock(&driver->hdlc_recovery_mutex);
|
||||
diag_hdlc_start_recovery(buf, len, info);
|
||||
diag_hdlc_start_recovery(buf, len, pid);
|
||||
break;
|
||||
}
|
||||
if ((pkt_len + header_len) > (len - read_bytes)) {
|
||||
|
@ -1527,13 +1560,13 @@ start:
|
|||
if (*(uint8_t *)(data_ptr + actual_pkt->length) !=
|
||||
CONTROL_CHAR) {
|
||||
mutex_unlock(&driver->hdlc_recovery_mutex);
|
||||
diag_hdlc_start_recovery(buf, len, info);
|
||||
diag_hdlc_start_recovery(buf, len, pid);
|
||||
mutex_lock(&driver->hdlc_recovery_mutex);
|
||||
}
|
||||
else
|
||||
hdlc_reset = 0;
|
||||
err = diag_process_apps_pkt(data_ptr,
|
||||
actual_pkt->length, info);
|
||||
actual_pkt->length, pid);
|
||||
if (err) {
|
||||
mutex_unlock(&driver->hdlc_recovery_mutex);
|
||||
break;
|
||||
|
@ -1552,9 +1585,9 @@ static int diagfwd_mux_read_done(unsigned char *buf, int len, int ctxt)
|
|||
return -EINVAL;
|
||||
|
||||
if (!driver->hdlc_disabled)
|
||||
diag_process_hdlc_pkt(buf, len, NULL);
|
||||
diag_process_hdlc_pkt(buf, len, 0);
|
||||
else
|
||||
diag_process_non_hdlc_pkt(buf, len, NULL);
|
||||
diag_process_non_hdlc_pkt(buf, len, 0);
|
||||
|
||||
diag_mux_queue_read(ctxt);
|
||||
return 0;
|
||||
|
|
|
@ -30,10 +30,8 @@
|
|||
|
||||
int diagfwd_init(void);
|
||||
void diagfwd_exit(void);
|
||||
void diag_process_hdlc_pkt(void *data, unsigned len,
|
||||
struct diag_md_session_t *info);
|
||||
void diag_process_non_hdlc_pkt(unsigned char *data, int len,
|
||||
struct diag_md_session_t *info);
|
||||
void diag_process_hdlc_pkt(void *data, unsigned int len, int pid);
|
||||
void diag_process_non_hdlc_pkt(unsigned char *data, int len, int pid);
|
||||
int chk_config_get_id(void);
|
||||
int chk_apps_only(void);
|
||||
int chk_apps_master(void);
|
||||
|
@ -45,10 +43,8 @@ int diag_cmd_get_mobile_id(unsigned char *src_buf, int src_len,
|
|||
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,
|
||||
struct diag_md_session_t *info);
|
||||
void diag_send_error_rsp(unsigned char *buf, int len,
|
||||
struct diag_md_session_t *info);
|
||||
int diag_process_apps_pkt(unsigned char *buf, int len, int pid);
|
||||
void diag_send_error_rsp(unsigned char *buf, int len, int pid);
|
||||
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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-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
|
||||
|
@ -316,14 +316,13 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info,
|
|||
diag_ws_release();
|
||||
return;
|
||||
}
|
||||
|
||||
session_info =
|
||||
diag_md_session_get_peripheral(peripheral);
|
||||
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);
|
||||
if (hdlc_disabled) {
|
||||
/* The data is raw and and on APPS side HDLC is disabled */
|
||||
if (!buf) {
|
||||
|
@ -638,12 +637,13 @@ 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);
|
||||
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…
Add table
Reference in a new issue