From b7b9ec64a7116232e7011ac047b710367a4fa12f Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 2 Nov 2016 19:08:00 +0530 Subject: [PATCH] diag: Add mutex protection while closing SMD On receiving feature mask add mutex protection while closing SMD and start reading from socket channel. CRs-Fixed: 980999 Change-Id: I01e5e8c9e0b03fa8b09f0ffd6857fe7e60a48091 Signed-off-by: Sreelakshmi Gownipalli Signed-off-by: Mohit Aggarwal Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar.h | 1 + drivers/char/diag/diagchar_core.c | 1 + drivers/char/diag/diagfwd_peripheral.c | 2 ++ drivers/char/diag/diagfwd_socket.c | 8 ++++++++ 4 files changed, 12 insertions(+) diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index 2aef98f4fe04..35cbe3b6b596 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -509,6 +509,7 @@ struct diagchar_dev { struct list_head cmd_reg_list; struct mutex cmd_reg_mutex; uint32_t cmd_reg_count; + struct mutex diagfwd_channel_mutex; /* Sizes that reflect memory pool sizes */ unsigned int poolsize; unsigned int poolsize_hdlc; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 39be6ef3735e..a5781f6db269 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -3394,6 +3394,7 @@ static int __init diagchar_init(void) mutex_init(&driver->diag_file_mutex); mutex_init(&driver->delayed_rsp_mutex); mutex_init(&apps_data_mutex); + mutex_init(&driver->diagfwd_channel_mutex); init_waitqueue_head(&driver->wait_q); INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn); INIT_WORK(&(driver->update_user_clients), diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 22b9e05086bd..731b42c56998 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -657,6 +657,7 @@ void diagfwd_close_transport(uint8_t transport, uint8_t peripheral) fwd_info = &early_init_info[transport][peripheral]; if (fwd_info->p_ops && fwd_info->p_ops->close) fwd_info->p_ops->close(fwd_info->ctxt); + mutex_lock(&driver->diagfwd_channel_mutex); fwd_info = &early_init_info[transport_open][peripheral]; dest_info = &peripheral_info[TYPE_CNTL][peripheral]; dest_info->inited = 1; @@ -677,6 +678,7 @@ void diagfwd_close_transport(uint8_t transport, uint8_t peripheral) diagfwd_late_open(dest_info); diagfwd_cntl_open(dest_info); init_fn(peripheral); + mutex_unlock(&driver->diagfwd_channel_mutex); diagfwd_queue_read(&peripheral_info[TYPE_DATA][peripheral]); diagfwd_queue_read(&peripheral_info[TYPE_CMD][peripheral]); } diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index fd927e931414..2f9ec51a17ba 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -959,7 +959,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) (info->data_ready > 0) || (!info->hdl) || (atomic_read(&info->diag_state) == 0)); if (err) { + mutex_lock(&driver->diagfwd_channel_mutex); diagfwd_channel_read_done(info->fwd_ctxt, buf, 0); + mutex_unlock(&driver->diagfwd_channel_mutex); return -ERESTARTSYS; } @@ -971,7 +973,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s closing read thread. diag state is closed\n", info->name); + mutex_lock(&driver->diagfwd_channel_mutex); diagfwd_channel_read_done(info->fwd_ctxt, buf, 0); + mutex_unlock(&driver->diagfwd_channel_mutex); return 0; } @@ -1038,8 +1042,10 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) if (total_recd > 0) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s read total bytes: %d\n", info->name, total_recd); + mutex_lock(&driver->diagfwd_channel_mutex); err = diagfwd_channel_read_done(info->fwd_ctxt, buf, total_recd); + mutex_unlock(&driver->diagfwd_channel_mutex); if (err) goto fail; } else { @@ -1052,7 +1058,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) return 0; fail: + mutex_lock(&driver->diagfwd_channel_mutex); diagfwd_channel_read_done(info->fwd_ctxt, buf, 0); + mutex_unlock(&driver->diagfwd_channel_mutex); return -EIO; }