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: Vivek Golani <vgolani@codeaurora.org>
This commit is contained in:
parent
97d292264c
commit
71f3e30f8e
@ -1345,11 +1345,26 @@ int diagfwd_channel_open(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)
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
|
||||
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)
|
||||
fwd_info->c_ops->close(fwd_info);
|
||||
|
||||
|
@ -678,7 +678,7 @@ static void diag_rpmsg_notify_rx_work_fn(struct work_struct *work)
|
||||
|
||||
if (!rpmsg_info->buf1 && !rpmsg_info->buf2) {
|
||||
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);
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
@ -738,7 +738,7 @@ end:
|
||||
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)
|
||||
return &rpmsg_cmd[peripheral];
|
||||
@ -771,7 +771,7 @@ void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num)
|
||||
return;
|
||||
}
|
||||
|
||||
rpmsg_info = get_info_ptr(type, peripheral);
|
||||
rpmsg_info = diag_get_rpmsg_info_ptr(type, peripheral);
|
||||
if (!rpmsg_info)
|
||||
return;
|
||||
|
||||
@ -849,6 +849,7 @@ static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
|
||||
mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->hdl = NULL;
|
||||
rpmsg_info->fwd_ctxt = NULL;
|
||||
rpmsg_info->probed = 0;
|
||||
atomic_set(&rpmsg_info->opened, 0);
|
||||
atomic_set(&rpmsg_info->diag_state, 0);
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
@ -1046,6 +1047,7 @@ static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
rpmsg_info->hdl = rpdev;
|
||||
atomic_set(&rpmsg_info->opened, 1);
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->probed = 1;
|
||||
dev_set_drvdata(&rpdev->dev, rpmsg_info);
|
||||
diagfwd_channel_read(rpmsg_info->fwd_ctxt);
|
||||
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]);
|
||||
atomic_set(&rpmsg_info->opened, 0);
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->probed = 0;
|
||||
queue_work(rpmsg_info->wq, &rpmsg_info->close_work);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ struct diag_rpmsg_info {
|
||||
uint8_t peripheral;
|
||||
uint8_t type;
|
||||
uint8_t inited;
|
||||
uint8_t probed;
|
||||
atomic_t opened;
|
||||
atomic_t diag_state;
|
||||
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);
|
||||
int diag_rpmsg_check_state(void *ctxt);
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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>
|
||||
@ -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 {
|
||||
unsigned int processor;
|
||||
char *name;
|
||||
@ -611,7 +627,9 @@ static void socket_read_work_fn(struct work_struct *work)
|
||||
err = sock_error(info->hdl->sk);
|
||||
mutex_unlock(&info->socket_info_mutex);
|
||||
if (unlikely(err == -ENETRESET)) {
|
||||
info->reset_flag = 1;
|
||||
socket_close_channel(info);
|
||||
info->reset_flag = 0;
|
||||
if (info->port_type == PORT_TYPE_SERVER)
|
||||
socket_init_work_fn(&info->init_work);
|
||||
diag_ws_release();
|
||||
@ -831,7 +849,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
|
||||
mutex_lock(channel_mutex);
|
||||
diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
|
||||
mutex_unlock(channel_mutex);
|
||||
info->reset_flag = 1;
|
||||
socket_close_channel(info);
|
||||
info->reset_flag = 0;
|
||||
if (info->port_type == PORT_TYPE_SERVER)
|
||||
socket_init_work_fn(&info->init_work);
|
||||
return read_len;
|
||||
@ -980,6 +1000,7 @@ static void __diag_socket_init(struct diag_socket_info *info)
|
||||
info->hdl = NULL;
|
||||
info->fwd_ctxt = NULL;
|
||||
info->data_ready = 0;
|
||||
info->reset_flag = 0;
|
||||
atomic_set(&info->flow_cnt, 0);
|
||||
spin_lock_init(&info->lock);
|
||||
strlcpy(wq_name, info->name, sizeof(wq_name));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
@ -33,6 +33,7 @@ struct diag_socket_info {
|
||||
uint8_t type;
|
||||
uint8_t port_type;
|
||||
uint8_t inited;
|
||||
uint8_t reset_flag;
|
||||
atomic_t opened;
|
||||
atomic_t diag_state;
|
||||
uint32_t pkt_len;
|
||||
@ -68,4 +69,5 @@ int diag_socket_check_state(void *ctxt);
|
||||
int diag_socket_init(void);
|
||||
void diag_socket_exit(void);
|
||||
int diag_socket_init_peripheral(uint8_t peripheral);
|
||||
struct diag_socket_info *diag_get_socket_info_ptr(int type, int peripheral);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user