Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83a00cec authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: HDLC changes for splitting the data stream"

parents af2c9a52 40240db5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -402,6 +402,8 @@ struct diag_logging_mode_param_t {
struct diag_md_session_t {
	int pid;
	int peripheral_mask;
	uint8_t hdlc_disabled;
	struct timer_list hdlc_reset_timer;
	struct diag_mask_info *msg_mask;
	struct diag_mask_info *log_mask;
	struct diag_mask_info *event_mask;
@@ -550,6 +552,7 @@ struct diagchar_dev {
	struct workqueue_struct *diag_wq;
	struct work_struct diag_drain_work;
	struct work_struct update_user_clients;
	struct work_struct update_md_clients;
	struct workqueue_struct *diag_cntl_wq;
	uint8_t log_on_demand_support;
	uint8_t *apps_req_buf;
+60 −13
Original line number Diff line number Diff line
@@ -226,12 +226,25 @@ void diag_update_user_client_work_fn(struct work_struct *work)
	diag_update_userspace_clients(HDLC_SUPPORT_TYPE);
}

static void diag_update_md_client_work_fn(struct work_struct *work)
{
	diag_update_md_clients(HDLC_SUPPORT_TYPE);
}

void diag_drain_work_fn(struct work_struct *work)
{
	timer_in_progress = 0;
	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled = 0;

	timer_in_progress = 0;
	mutex_lock(&apps_data_mutex);
	if (!driver->hdlc_disabled)
	session_info = diag_md_session_get_peripheral(APPS_DATA);
	if (session_info)
		hdlc_disabled = session_info->hdlc_disabled;
	else
		hdlc_disabled = driver->hdlc_disabled;

	if (!hdlc_disabled)
		diag_drain_apps_data(&hdlc_data);
	else
		diag_drain_apps_data(&non_hdlc_data);
@@ -851,6 +864,8 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len,
	struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
	struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
	int bridge_index = proc - 1;
	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled = 0;

	if (!buf)
		return -EINVAL;
@@ -875,8 +890,12 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len,

	if (driver->hdlc_encode_buf_len != 0)
		return -EAGAIN;

	if (driver->hdlc_disabled) {
	session_info = diag_md_session_get_peripheral(APPS_DATA);
	if (session_info)
		hdlc_disabled = session_info->hdlc_disabled;
	else
		hdlc_disabled = driver->hdlc_disabled;
	if (hdlc_disabled) {
		payload = *(uint16_t *)(buf + 2);
		driver->hdlc_encode_buf_len = payload;
		/*
@@ -1170,6 +1189,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc)
			driver->md_session_map[i] = new_session;
		}
		driver->md_session_mode = DIAG_MD_NORMAL;
		setup_timer(&new_session->hdlc_reset_timer,
			diag_md_hdlc_reset_timer_func,
			new_session->pid);
		DIAG_LOG(DIAG_DEBUG_USERSPACE,
			 "created session in normal mode\n");
		mutex_unlock(&driver->md_session_lock);
@@ -1213,7 +1235,6 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc)
			 "return value of msg copy. err %d\n", err);
		goto fail_peripheral;
	}

	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if ((MD_PERIPHERAL_MASK(i) & peripheral_mask) == 0)
			continue;
@@ -1226,6 +1247,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc)
		new_session->peripheral_mask |= MD_PERIPHERAL_MASK(i);
		driver->md_session_map[i] = new_session;
		driver->md_session_mask |= MD_PERIPHERAL_MASK(i);
		setup_timer(&new_session->hdlc_reset_timer,
			diag_md_hdlc_reset_timer_func,
			new_session->pid);
	}
	driver->md_session_mode = DIAG_MD_PERIPHERAL;
	mutex_unlock(&driver->md_session_lock);
@@ -1275,6 +1299,7 @@ static void diag_md_session_close(struct diag_md_session_t *session_info)
		diag_event_mask_free(session_info->event_mask);
		kfree(session_info->event_mask);
		session_info->event_mask = NULL;
		del_timer(&session_info->hdlc_reset_timer);
	}

	for (i = 0; i < NUM_MD_SESSIONS && !found; i++) {
@@ -1771,15 +1796,21 @@ static int diag_ioctl_dci_support(unsigned long ioarg)
static int diag_ioctl_hdlc_toggle(unsigned long ioarg)
{
	uint8_t hdlc_support;
	struct diag_md_session_t *session_info = NULL;

	session_info = diag_md_session_get_pid(current->tgid);
	if (copy_from_user(&hdlc_support, (void __user *)ioarg,
				sizeof(uint8_t)))
		return -EFAULT;

	mutex_lock(&driver->hdlc_disable_mutex);
	if (session_info) {
		mutex_lock(&driver->md_session_lock);
		session_info->hdlc_disabled = hdlc_support;
		mutex_unlock(&driver->md_session_lock);
	} else
		driver->hdlc_disabled = hdlc_support;
	mutex_unlock(&driver->hdlc_disable_mutex);
	diag_update_userspace_clients(HDLC_SUPPORT_TYPE);
	diag_update_md_clients(HDLC_SUPPORT_TYPE);

	return 0;
}
@@ -2465,6 +2496,7 @@ static int diag_user_process_userspace_data(const char __user *buf, int len)
	int remote_proc = 0;
	int token_offset = 0;
	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled;

	if (!buf || len <= 0 || len > USER_SPACE_DATA) {
		pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n",
@@ -2518,7 +2550,11 @@ static int diag_user_process_userspace_data(const char __user *buf, int len)
				__func__, current->tgid);
			return -EINVAL;
		}
		if (!driver->hdlc_disabled)
		if (session_info)
			hdlc_disabled = session_info->hdlc_disabled;
		else
			hdlc_disabled = driver->hdlc_disabled;
		if (!hdlc_disabled)
			diag_process_hdlc_pkt((void *)
				(driver->user_space_data_buf),
				len, session_info);
@@ -2548,6 +2584,8 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
	int stm_size = 0;
	const int mempool = POOL_TYPE_COPY;
	unsigned char *user_space_data = NULL;
	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled;

	if (!buf || len <= 0 || len > DIAG_MAX_RSP_SIZE) {
		pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n",
@@ -2600,13 +2638,17 @@ static int diag_user_process_apps_data(const char __user *buf, int len,

	mutex_lock(&apps_data_mutex);
	mutex_lock(&driver->hdlc_disable_mutex);
	if (driver->hdlc_disabled) {
	session_info = diag_md_session_get_peripheral(APPS_DATA);
	if (session_info)
		hdlc_disabled = session_info->hdlc_disabled;
	else
		hdlc_disabled = driver->hdlc_disabled;
	if (hdlc_disabled)
		ret = diag_process_apps_data_non_hdlc(user_space_data, len,
						      pkt_type);
	} else {
	else
		ret = diag_process_apps_data_hdlc(user_space_data, len,
						  pkt_type);
	}
	mutex_unlock(&driver->hdlc_disable_mutex);
	mutex_unlock(&apps_data_mutex);

@@ -2676,7 +2718,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
		data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE;
		driver->data_ready[index] ^= HDLC_SUPPORT_TYPE;
		COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int));
		COPY_USER_SPACE_OR_EXIT(buf+4, driver->hdlc_disabled,
		session_info = diag_md_session_get_pid(current->tgid);
		if (session_info)
			COPY_USER_SPACE_OR_EXIT(buf+4,
					session_info->hdlc_disabled,
					sizeof(uint8_t));
		goto exit;
	}
@@ -3247,6 +3292,8 @@ static int __init diagchar_init(void)
	INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
	INIT_WORK(&(driver->update_user_clients),
			diag_update_user_client_work_fn);
	INIT_WORK(&(driver->update_md_clients),
			diag_update_md_client_work_fn);
	diag_ws_init();
	diag_stats_init();
	diag_debug_init();
+71 −12
Original line number Diff line number Diff line
@@ -382,7 +382,16 @@ static void encode_rsp_and_send(unsigned char *buf, int len)

void diag_send_rsp(unsigned char *buf, int len)
{
	if (driver->hdlc_disabled)
	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled;

	session_info = diag_md_session_get_peripheral(APPS_DATA);
	if (session_info)
		hdlc_disabled = session_info->hdlc_disabled;
	else
		hdlc_disabled = driver->hdlc_disabled;

	if (hdlc_disabled)
		pack_rsp_and_send(buf, len);
	else
		encode_rsp_and_send(buf, len);
@@ -444,6 +453,24 @@ void diag_update_userspace_clients(unsigned int type)
	mutex_unlock(&driver->diagchar_mutex);
}

void diag_update_md_clients(unsigned int type)
{
	int i, j;

	mutex_lock(&driver->diagchar_mutex);
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (driver->md_session_map[i] != NULL)
			for (j = 0; j < driver->num_clients; j++) {
				if (driver->client_map[j].pid != 0 &&
					driver->client_map[j].pid ==
					driver->md_session_map[i]->pid)
					driver->data_ready[j] |= type;
				break;
			}
	}
	wake_up_interruptible(&driver->wait_q);
	mutex_unlock(&driver->diagchar_mutex);
}
void diag_update_sleeping_process(int process_id, int data_type)
{
	int i;
@@ -889,6 +916,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
	if (temp_entry) {
		reg_item = container_of(temp_entry, struct diag_cmd_reg_t,
								entry);
		if (info) {
			if (MD_PERIPHERAL_MASK(reg_item->proc) &
				info->peripheral_mask)
				write_len = diag_send_data(reg_item, buf, len);
		} else
			write_len = diag_send_data(reg_item, buf, len);
		mutex_unlock(&driver->cmd_reg_mutex);
		return write_len;
@@ -1048,8 +1080,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
		 */
		pr_debug("diag: In %s, disabling HDLC encoding\n",
		       __func__);
		if (info)
			info->hdlc_disabled = 1;
		else
			driver->hdlc_disabled = 1;
		diag_update_userspace_clients(HDLC_SUPPORT_TYPE);
		diag_update_md_clients(HDLC_SUPPORT_TYPE);
		mutex_unlock(&driver->hdlc_disable_mutex);
		return 0;
	}
@@ -1212,6 +1247,7 @@ static int diagfwd_mux_close(int id, int mode)
		pr_debug("diag: In %s, re-enabling HDLC encoding\n",
		       __func__);
		mutex_lock(&driver->hdlc_disable_mutex);
		if (driver->md_session_mode == DIAG_MD_NONE)
			driver->hdlc_disabled = 0;
		mutex_unlock(&driver->hdlc_disable_mutex);
		queue_work(driver->diag_wq,
@@ -1224,10 +1260,14 @@ static int diagfwd_mux_close(int id, int mode)

static uint8_t hdlc_reset;

static void hdlc_reset_timer_start(void)
static void hdlc_reset_timer_start(struct diag_md_session_t *info)
{
	if (!hdlc_timer_in_progress) {
		hdlc_timer_in_progress = 1;
		if (info)
			mod_timer(&info->hdlc_reset_timer,
			  jiffies + msecs_to_jiffies(200));
		else
			mod_timer(&driver->hdlc_reset_timer,
			  jiffies + msecs_to_jiffies(200));
	}
@@ -1235,7 +1275,6 @@ static void hdlc_reset_timer_start(void)

static void hdlc_reset_timer_func(unsigned long data)
{

	pr_debug("diag: In %s, re-enabling HDLC encoding\n",
		       __func__);
	if (hdlc_reset) {
@@ -1246,6 +1285,22 @@ static void hdlc_reset_timer_func(unsigned long data)
	hdlc_timer_in_progress = 0;
}

void diag_md_hdlc_reset_timer_func(unsigned long pid)
{
	struct diag_md_session_t *session_info = NULL;

	pr_debug("diag: In %s, re-enabling HDLC encoding\n",
		       __func__);
	if (hdlc_reset) {
		session_info = diag_md_session_get_pid(pid);
		if (session_info)
			session_info->hdlc_disabled = 0;
		queue_work(driver->diag_wq,
			&(driver->update_md_clients));
	}
	hdlc_timer_in_progress = 0;
}

static void diag_hdlc_start_recovery(unsigned char *buf, int len,
				     struct diag_md_session_t *info)
{
@@ -1255,7 +1310,7 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len,
	struct diag_pkt_frame_t *actual_pkt = NULL;

	hdlc_reset = 1;
	hdlc_reset_timer_start();
	hdlc_reset_timer_start(info);

	actual_pkt = (struct diag_pkt_frame_t *)buf;
	for (i = 0; i < len; i++) {
@@ -1274,9 +1329,13 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len,
			pr_err("diag: In %s, re-enabling HDLC encoding\n",
					__func__);
			mutex_lock(&driver->hdlc_disable_mutex);
			if (info)
				info->hdlc_disabled = 0;
			else
				driver->hdlc_disabled = 0;
			mutex_unlock(&driver->hdlc_disable_mutex);
			diag_update_userspace_clients(HDLC_SUPPORT_TYPE);
			diag_update_md_clients(HDLC_SUPPORT_TYPE);

			return;
		}
	}
+2 −0
Original line number Diff line number Diff line
@@ -48,4 +48,6 @@ int diag_process_apps_pkt(unsigned char *buf, int len,
void diag_send_error_rsp(unsigned char *buf, int len);
void diag_update_pkt_buffer(unsigned char *buf, uint32_t len, int type);
int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf);
void diag_md_hdlc_reset_timer_func(unsigned long pid);
void diag_update_md_clients(unsigned int type);
#endif
+11 −4
Original line number Diff line number Diff line
@@ -219,7 +219,8 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,
	int write_len = 0;
	unsigned char *write_buf = NULL;
	struct diagfwd_buf_t *temp_buf = NULL;

	struct diag_md_session_t *session_info = NULL;
	uint8_t hdlc_disabled = 0;
	if (!fwd_info || !buf || len <= 0) {
		diag_ws_release();
		return;
@@ -239,6 +240,12 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,

	mutex_lock(&driver->hdlc_disable_mutex);
	mutex_lock(&fwd_info->data_mutex);
	session_info = diag_md_session_get_peripheral(fwd_info->peripheral);
	if (session_info)
		hdlc_disabled = session_info->hdlc_disabled;
	else
		hdlc_disabled = driver->hdlc_disabled;

	if (!driver->feature[fwd_info->peripheral].encode_hdlc) {
		if (fwd_info->buf_1 && fwd_info->buf_1->data == buf) {
			temp_buf = fwd_info->buf_1;
@@ -253,7 +260,7 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,
			goto end;
		}
		write_len = len;
	} else if (driver->hdlc_disabled) {
	} else if (hdlc_disabled) {
		/* The data is raw and and on APPS side HDLC is disabled */
		if (fwd_info->buf_1 && fwd_info->buf_1->data_raw == buf) {
			temp_buf = fwd_info->buf_1;