commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=ab2db33b4ba5e068373517100dd05e0686e952e1 branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk
before destroy session, wait until all messages on tx list of session complete, and wait for remote close ack, at last free the session Signed-off-by: Steven Miao <[email protected]> --- drivers/staging/icc/core/protocol.c | 35 ++++++++++++++++++++++++----------- 1 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/staging/icc/core/protocol.c b/drivers/staging/icc/core/protocol.c index 0d29b5b..f2f761a 100644 --- a/drivers/staging/icc/core/protocol.c +++ b/drivers/staging/icc/core/protocol.c @@ -227,7 +227,7 @@ static int sm_send_message_internal(struct sm_msg *msg, int dst_cpu, int src_cpu) { int ret = 0; - sm_debug("%s: dst %d src %d\n", __func__, dst_cpu, src_cpu); + sm_debug("%s: dst %d src %d %08x\n", __func__, dst_cpu, src_cpu, msg->type); ret = sm_message_enqueue(dst_cpu, src_cpu, msg); if (!ret) icc_send_ipi_cpu(dst_cpu, IRQ_SUPPLE_0); @@ -752,6 +752,7 @@ static int sm_close_session(sm_uint32_t index) static int sm_destroy_session(sm_uint32_t session_idx) { struct sm_message *message; + struct sm_message *uncompleted; struct sm_msg *msg; struct sm_session *session; struct sm_session_table *table = icc_info->sessions_table; @@ -776,9 +777,24 @@ static int sm_destroy_session(sm_uint32_t session_idx) } mutex_unlock(&icc_info->sessions_table->lock); - if (session->flags == SM_CONNECT) + mutex_lock(&icc_info->sessions_table->lock); + while (!list_empty(&session->tx_messages)) { + mutex_unlock(&icc_info->sessions_table->lock); + schedule_timeout(500); + mutex_lock(&icc_info->sessions_table->lock); + } + mutex_unlock(&icc_info->sessions_table->lock); + + if (session->flags == SM_CONNECT) { sm_send_close(session, session->remote_ep, 1); + interruptible_sleep_on(&session->rx_wait); + if (signal_pending(current)) { + sm_debug("signal\n"); + return -EINTR; + } + } + sm_free_session(session_idx, table); return 0; } @@ -1311,19 +1327,16 @@ void msg_handle(int cpu) sm_debug("session %p index %d msg type%x\n", session, index, msg->type); if (!session) { + sm_debug("discard msg type %x\n", msg->type); sm_message_dequeue(cpu, msg); + wake_up(&icc_info->iccq_tx_wait); return; } - if (session) { - if (session->proto_ops->recvmsg) - session->proto_ops->recvmsg(msg, session); - else - sm_debug("session type not supported\n"); - } else { - sm_debug("discard msg type %x sessiontype %x\n", msg->type, session->type); - sm_message_dequeue(cpu, msg); - } + if (session->proto_ops->recvmsg) + session->proto_ops->recvmsg(msg, session); + else + sm_debug("session type not supported\n"); } static int message_queue_thread(void *d)
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
