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

Commit 71f3e30f authored by Vivek Golani's avatar Vivek Golani Committed by Manjunatha Madana
Browse files

diag: Enable graceful transfer of transport



Avoid channel close by setting flags if socket
transport close is invoked after rpmsg transport
has been probed.

Change-Id: I5d94894e05bbbe079a566d9356eb08a6aeac7799
Signed-off-by: default avatarVivek Golani <vgolani@codeaurora.org>
parent 97d29226
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -1345,11 +1345,26 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info)


int diagfwd_channel_close(struct diagfwd_info *fwd_info)
int diagfwd_channel_close(struct diagfwd_info *fwd_info)
{
{
	struct diag_rpmsg_info *rpmsg_info = NULL;
	struct diag_socket_info *socket_info = NULL;

	if (!fwd_info)
	if (!fwd_info)
		return -EIO;
		return -EIO;


	mutex_lock(&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
	mutex_lock(&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
	fwd_info->ch_open = 0;
	fwd_info->ch_open = 0;
	rpmsg_info = diag_get_rpmsg_info_ptr(fwd_info->type,
						fwd_info->peripheral);
	socket_info = diag_get_socket_info_ptr(fwd_info->type,
						fwd_info->peripheral);

	if (rpmsg_info && socket_info && rpmsg_info->probed
					&& socket_info->reset_flag) {
		mutex_unlock(
			&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
		return 0;
	}

	if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->close)
	if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->close)
		fwd_info->c_ops->close(fwd_info);
		fwd_info->c_ops->close(fwd_info);


+6 −3
Original line number Original line Diff line number Diff line
@@ -678,7 +678,7 @@ static void diag_rpmsg_notify_rx_work_fn(struct work_struct *work)


		if (!rpmsg_info->buf1 && !rpmsg_info->buf2) {
		if (!rpmsg_info->buf1 && !rpmsg_info->buf2) {
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
					"dropping data for %s len %d\n",
					"retry data send for %s len %d\n",
					rpmsg_info->name, rx_item->rx_buf_size);
					rpmsg_info->name, rx_item->rx_buf_size);
			err_flag = 1;
			err_flag = 1;
			goto err_handling;
			goto err_handling;
@@ -738,7 +738,7 @@ static void diag_rpmsg_notify_rx_work_fn(struct work_struct *work)
	return;
	return;
}
}


static struct diag_rpmsg_info *get_info_ptr(int type, int peripheral)
struct diag_rpmsg_info *diag_get_rpmsg_info_ptr(int type, int peripheral)
{
{
	if (type == TYPE_CMD)
	if (type == TYPE_CMD)
		return &rpmsg_cmd[peripheral];
		return &rpmsg_cmd[peripheral];
@@ -771,7 +771,7 @@ void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num)
		return;
		return;
	}
	}


	rpmsg_info =  get_info_ptr(type, peripheral);
	rpmsg_info =  diag_get_rpmsg_info_ptr(type, peripheral);
	if (!rpmsg_info)
	if (!rpmsg_info)
		return;
		return;


@@ -849,6 +849,7 @@ static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
	mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
	mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
	rpmsg_info->hdl = NULL;
	rpmsg_info->hdl = NULL;
	rpmsg_info->fwd_ctxt = NULL;
	rpmsg_info->fwd_ctxt = NULL;
	rpmsg_info->probed = 0;
	atomic_set(&rpmsg_info->opened, 0);
	atomic_set(&rpmsg_info->opened, 0);
	atomic_set(&rpmsg_info->diag_state, 0);
	atomic_set(&rpmsg_info->diag_state, 0);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
@@ -1046,6 +1047,7 @@ static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
		rpmsg_info->hdl = rpdev;
		rpmsg_info->hdl = rpdev;
		atomic_set(&rpmsg_info->opened, 1);
		atomic_set(&rpmsg_info->opened, 1);
		mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		rpmsg_info->probed = 1;
		dev_set_drvdata(&rpdev->dev, rpmsg_info);
		dev_set_drvdata(&rpdev->dev, rpmsg_info);
		diagfwd_channel_read(rpmsg_info->fwd_ctxt);
		diagfwd_channel_read(rpmsg_info->fwd_ctxt);
		queue_work(rpmsg_info->wq, &rpmsg_info->open_work);
		queue_work(rpmsg_info->wq, &rpmsg_info->open_work);
@@ -1075,6 +1077,7 @@ static void diag_rpmsg_remove(struct rpmsg_device *rpdev)
		mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		atomic_set(&rpmsg_info->opened, 0);
		atomic_set(&rpmsg_info->opened, 0);
		mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
		rpmsg_info->probed = 0;
		queue_work(rpmsg_info->wq, &rpmsg_info->close_work);
		queue_work(rpmsg_info->wq, &rpmsg_info->close_work);
	}
	}
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@ struct diag_rpmsg_info {
	uint8_t peripheral;
	uint8_t peripheral;
	uint8_t type;
	uint8_t type;
	uint8_t inited;
	uint8_t inited;
	uint8_t probed;
	atomic_t opened;
	atomic_t opened;
	atomic_t diag_state;
	atomic_t diag_state;
	uint32_t fifo_size;
	uint32_t fifo_size;
@@ -44,5 +45,6 @@ void diag_rpmsg_early_exit(void);
void diag_rpmsg_invalidate(void *ctxt, struct diagfwd_info *fwd_ctxt);
void diag_rpmsg_invalidate(void *ctxt, struct diagfwd_info *fwd_ctxt);
int diag_rpmsg_check_state(void *ctxt);
int diag_rpmsg_check_state(void *ctxt);
void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num);
void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num);
struct diag_rpmsg_info *diag_get_rpmsg_info_ptr(int type, int peripheral);


#endif
#endif
+22 −1
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
 */
 */


#include <linux/slab.h>
#include <linux/slab.h>
@@ -244,6 +244,22 @@ struct diag_socket_info socket_dci_cmd[NUM_PERIPHERALS] = {
	}
	}
};
};


struct diag_socket_info *diag_get_socket_info_ptr(int type, int peripheral)
{
	if (type == TYPE_CMD)
		return &socket_cmd[peripheral];
	else if (type == TYPE_CNTL)
		return &socket_cntl[peripheral];
	else if (type == TYPE_DATA)
		return &socket_data[peripheral];
	else if (type == TYPE_DCI_CMD)
		return &socket_dci_cmd[peripheral];
	else if (type == TYPE_DCI)
		return &socket_dci[peripheral];
	else
		return NULL;
}

struct restart_notifier_block {
struct restart_notifier_block {
	unsigned int processor;
	unsigned int processor;
	char *name;
	char *name;
@@ -611,7 +627,9 @@ static void socket_read_work_fn(struct work_struct *work)
	err = sock_error(info->hdl->sk);
	err = sock_error(info->hdl->sk);
	mutex_unlock(&info->socket_info_mutex);
	mutex_unlock(&info->socket_info_mutex);
	if (unlikely(err == -ENETRESET)) {
	if (unlikely(err == -ENETRESET)) {
		info->reset_flag = 1;
		socket_close_channel(info);
		socket_close_channel(info);
		info->reset_flag = 0;
		if (info->port_type == PORT_TYPE_SERVER)
		if (info->port_type == PORT_TYPE_SERVER)
			socket_init_work_fn(&info->init_work);
			socket_init_work_fn(&info->init_work);
		diag_ws_release();
		diag_ws_release();
@@ -831,7 +849,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
			mutex_lock(channel_mutex);
			mutex_lock(channel_mutex);
			diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
			diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
			mutex_unlock(channel_mutex);
			mutex_unlock(channel_mutex);
			info->reset_flag = 1;
			socket_close_channel(info);
			socket_close_channel(info);
			info->reset_flag = 0;
			if (info->port_type == PORT_TYPE_SERVER)
			if (info->port_type == PORT_TYPE_SERVER)
				socket_init_work_fn(&info->init_work);
				socket_init_work_fn(&info->init_work);
			return read_len;
			return read_len;
@@ -980,6 +1000,7 @@ static void __diag_socket_init(struct diag_socket_info *info)
	info->hdl = NULL;
	info->hdl = NULL;
	info->fwd_ctxt = NULL;
	info->fwd_ctxt = NULL;
	info->data_ready = 0;
	info->data_ready = 0;
	info->reset_flag = 0;
	atomic_set(&info->flow_cnt, 0);
	atomic_set(&info->flow_cnt, 0);
	spin_lock_init(&info->lock);
	spin_lock_init(&info->lock);
	strlcpy(wq_name, info->name, sizeof(wq_name));
	strlcpy(wq_name, info->name, sizeof(wq_name));
+3 −1
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
 */
 */


#ifndef DIAGFWD_SOCKET_H
#ifndef DIAGFWD_SOCKET_H
@@ -33,6 +33,7 @@ struct diag_socket_info {
	uint8_t type;
	uint8_t type;
	uint8_t port_type;
	uint8_t port_type;
	uint8_t inited;
	uint8_t inited;
	uint8_t reset_flag;
	atomic_t opened;
	atomic_t opened;
	atomic_t diag_state;
	atomic_t diag_state;
	uint32_t pkt_len;
	uint32_t pkt_len;
@@ -68,4 +69,5 @@ int diag_socket_check_state(void *ctxt);
int diag_socket_init(void);
int diag_socket_init(void);
void diag_socket_exit(void);
void diag_socket_exit(void);
int diag_socket_init_peripheral(uint8_t peripheral);
int diag_socket_init_peripheral(uint8_t peripheral);
struct diag_socket_info *diag_get_socket_info_ptr(int type, int peripheral);
#endif
#endif