From 01ef1d9a564394ce600a322b24c449055bf52b7e Mon Sep 17 00:00:00 2001 From: Sreelakshmi Gownipalli Date: Tue, 30 Aug 2016 11:08:38 -0700 Subject: [PATCH] diag: Do not open glink channel twice When diag receives two link state notifications it tries to open the glink channel which is already open. Add a check to not open the channel if the channel is already open. Change-Id: I5818d2731b53af37d796d421c5ae9a4b7fa52405 Signed-off-by: Sreelakshmi Gownipalli --- drivers/char/diag/diagfwd_glink.c | 18 +++++++++++------- drivers/char/diag/diagfwd_glink.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/char/diag/diagfwd_glink.c b/drivers/char/diag/diagfwd_glink.c index 0a6d8bb7b21f..fea1b74aacae 100644 --- a/drivers/char/diag/diagfwd_glink.c +++ b/drivers/char/diag/diagfwd_glink.c @@ -475,7 +475,7 @@ static void diag_glink_open_work_fn(struct work_struct *work) struct glink_open_config open_cfg; void *handle = NULL; - if (!glink_info) + if (!glink_info || glink_info->hdl) return; memset(&open_cfg, 0, sizeof(struct glink_open_config)); @@ -499,11 +499,12 @@ static void diag_glink_close_work_fn(struct work_struct *work) struct diag_glink_info *glink_info = container_of(work, struct diag_glink_info, close_work); - if (!glink_info->inited) + if (!glink_info || !glink_info->inited || !glink_info->hdl) return; glink_close(glink_info->hdl); atomic_set(&glink_info->opened, 0); + glink_info->hdl = NULL; diagfwd_channel_close(glink_info->fwd_ctxt); } @@ -586,6 +587,7 @@ static void __diag_glink_init(struct diag_glink_info *glink_info) { char wq_name[DIAG_GLINK_NAME_SZ + 12]; struct glink_link_info link_info; + void *link_state_handle = NULL; if (!glink_info) return; @@ -606,23 +608,25 @@ static void __diag_glink_init(struct diag_glink_info *glink_info) INIT_WORK(&(glink_info->read_work), diag_glink_read_work_fn); link_info.glink_link_state_notif_cb = diag_glink_notify_cb; link_info.transport = NULL; - strlcpy((char *)link_info.edge, glink_info->edge, - sizeof(link_info.edge)); - glink_info->hdl = glink_register_link_state_cb(&link_info, + link_info.edge = glink_info->edge; + glink_info->link_state_handle = NULL; + link_state_handle = glink_register_link_state_cb(&link_info, (void *)glink_info); - if (IS_ERR_OR_NULL(glink_info->hdl)) { + if (IS_ERR_OR_NULL(link_state_handle)) { pr_err("diag: In %s, unable to register for glink channel %s\n", __func__, glink_info->name); destroy_workqueue(glink_info->wq); return; } + glink_info->link_state_handle = link_state_handle; glink_info->fwd_ctxt = NULL; atomic_set(&glink_info->tx_intent_ready, 0); atomic_set(&glink_info->opened, 0); atomic_set(&glink_info->diag_state, 0); DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s initialized fwd_ctxt: %pK hdl: %pK\n", - glink_info->name, glink_info->fwd_ctxt, glink_info->hdl); + glink_info->name, glink_info->fwd_ctxt, + glink_info->link_state_handle); } void diag_glink_invalidate(void *ctxt, struct diagfwd_info *fwd_ctxt) diff --git a/drivers/char/diag/diagfwd_glink.h b/drivers/char/diag/diagfwd_glink.h index 3f00a7ed60a8..bad4629b5ab8 100644 --- a/drivers/char/diag/diagfwd_glink.h +++ b/drivers/char/diag/diagfwd_glink.h @@ -25,6 +25,7 @@ struct diag_glink_info { uint32_t fifo_size; atomic_t tx_intent_ready; void *hdl; + void *link_state_handle; char edge[DIAG_GLINK_NAME_SZ]; char name[DIAG_GLINK_NAME_SZ]; struct mutex lock;