commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=4d1f0c462be1c586595e45f392263571720e49ac branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk
Signed-off-by: Steven Miao <[email protected]> --- drivers/staging/icc/core/protocol.c | 68 +++++++++++++++++++--------------- drivers/staging/icc/include/icc.h | 5 ++- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/staging/icc/core/protocol.c b/drivers/staging/icc/core/protocol.c index 8e1bced..5cbdb48 100644 --- a/drivers/staging/icc/core/protocol.c +++ b/drivers/staging/icc/core/protocol.c @@ -99,7 +99,7 @@ static struct sm_message_queue *sm_find_queue(struct sm_message *message, struct uint16_t dst = message->dst; struct sm_icc_desc *icc_info = bfin_icc->icc_info; int i; - if (!message || !session) + if (!message) return NULL; for (i = 0; i < bfin_icc->peer_count; i++) { if (icc_info[i].peer_cpu == dst) @@ -108,10 +108,14 @@ static struct sm_message_queue *sm_find_queue(struct sm_message *message, struct if (i == bfin_icc->peer_count) return NULL; message->icc_info = &icc_info[i]; - if (session->queue_priority) - return icc_info[i].icc_queue; - else + if (!session) return icc_info[i].icc_high_queue; + else { + if (session->queue_priority) + return icc_info[i].icc_queue; + else + return icc_info[i].icc_high_queue; + } } static int init_sm_session_table(struct bfin_icc *icc) @@ -121,6 +125,7 @@ static int init_sm_session_table(struct bfin_icc *icc) if (!icc->sessions_table) return -ENOMEM; mutex_init(&icc->sessions_table->lock); + init_waitqueue_head(&icc->sessions_table->query_wait); icc->sessions_table->nfree = MAX_ENDPOINTS; return 0; } @@ -131,8 +136,12 @@ static int sm_message_enqueue(struct sm_message_queue *icc_queue, struct sm_msg struct sm_message_queue *outqueue = icc_queue + 1; uint16_t sent = sm_atomic_read(&outqueue->sent); uint16_t received = sm_atomic_read(&outqueue->received); + uint16_t pending = sent - received; - if ((sent - received) >= (SM_MSGQ_LEN - 1)) { + if (pending < 0) + pending += USHRT_MAX; + + if (pending >= (SM_MSGQ_LEN - 1)) { sm_debug("over run\n"); return -EAGAIN; } @@ -321,9 +330,13 @@ sm_send_control_msg(struct sm_session *session, uint32_t remote_ep, message->dst = dst_cpu; message->src = "" +retry: ret = sm_send_message_internal(session, message); - if (ret) - return -EAGAIN; + if (ret) { + interruptible_sleep_on(&message->icc_info->iccq_tx_wait); + goto retry; + } + kfree(message); return ret; @@ -721,21 +734,21 @@ static int sm_recv_packet(uint32_t session_idx, uint32_t *src_ep, return ret; } -static int sm_query_remote_ep(uint32_t session_idx, uint32_t dst_ep, +static int sm_query_remote_ep(uint32_t dst_ep, uint32_t dst_cpu) { - struct sm_session *session; - session = sm_index_to_session(session_idx); - if (!session) - return -EINVAL; - + int ret; mutex_lock(&bfin_icc->sessions_table->lock); - session->flags = SM_QUERY; + bfin_icc->sessions_table->query_status = 1; mutex_unlock(&bfin_icc->sessions_table->lock); - sm_send_control_msg(session, dst_ep, dst_cpu, 0, + sm_debug("%s dst_ep %d dst_cpu %d\n", __func__, dst_ep, dst_cpu); + sm_send_control_msg(NULL, dst_ep, dst_cpu, 0, 0, SM_QUERY_MSG); - wait_event_interruptible_timeout(session->rx_wait, - (session->flags == 0), HZ); + ret = wait_event_interruptible_timeout(bfin_icc->sessions_table->query_wait, + !bfin_icc->sessions_table->query_status, HZ); + if (ret == -ERESTARTSYS) + return ret; + sm_debug("received query ack\n"); return 0; } @@ -1119,7 +1132,7 @@ icc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) dma_free_coherent(NULL, pkt->buf_len, pkt->buf, pkt->paddr); break; case CMD_SM_QUERY_REMOTE_EP: - sm_query_remote_ep(session_idx, remote_ep, dst_cpu); + sm_query_remote_ep(remote_ep, dst_cpu); break; default: ret = -EINVAL; @@ -1468,22 +1481,18 @@ int __handle_general_msg(struct sm_msg *msg) if (session) { icc_info = get_icc_peer(msg); - sm_send_control_msg(session, msg->src_ep, + sm_send_control_msg(session, 0, icc_info->peer_cpu, 0, 0, SM_QUERY_ACK_MSG); } ret = 1; break; case SM_QUERY_ACK_MSG: - index = sm_find_session(msg->dst_ep, 0, bfin_icc->sessions_table); - session = sm_index_to_session(index); - - if (session) { - mutex_lock(&bfin_icc->sessions_table->lock); - session->flags = 0; - mutex_unlock(&bfin_icc->sessions_table->lock); - wake_up_interruptible(&session->rx_wait); - ret = 1; - } + mutex_lock(&bfin_icc->sessions_table->lock); + bfin_icc->sessions_table->query_status = 0; + mutex_unlock(&bfin_icc->sessions_table->lock); + wake_up_interruptible(&bfin_icc->sessions_table->query_wait); + ret = 1; + break; default: ret = 0; } @@ -1683,7 +1692,6 @@ static int __devinit bfin_icc_probe(struct platform_device *pdev) icc_info->icc_queue = (struct sm_message_queue *)icc_info->icc_high_queue + 2; memset(icc_info->icc_high_queue, 0, sizeof(struct sm_message_queue) * SM_MSGQ_NUM); - init_waitqueue_head(&icc->icc_rx_wait); init_waitqueue_head(&icc_info->iccq_tx_wait); icc_info->iccq_thread = kthread_run(message_queue_thread, icc_info, "iccqd"); diff --git a/drivers/staging/icc/include/icc.h b/drivers/staging/icc/include/icc.h index 410a6c5..a101a37 100644 --- a/drivers/staging/icc/include/icc.h +++ b/drivers/staging/icc/include/icc.h @@ -43,7 +43,6 @@ enum { #define SM_CONNECTING 0x2 #define SM_OPEN 0x4 #define SM_ACTIVE 0x8 -#define SM_QUERY 0x10 #define SM_BAD_ENDPOINT SM_MSG_TYPE(SP_GENERAL, 0) #define SM_BAD_MSG SM_MSG_TYPE(SP_GENERAL, 1) @@ -156,7 +155,7 @@ struct sm_message_queue { #define SM_MSGQ_NUM 4 /* 2 low bi-direction fifos and 2 high ones */ #define MSGQ_SIZE (sizeof(struct sm_message_queue) * SM_MSGQ_NUM) -#define DEBUG_MSG_LINE 128 +#define DEBUG_MSG_LINE 256 #define DEBUG_MSG_BUF_SIZE (DEBUG_MSG_LINE * SM_MSGQ_LEN) struct sm_icc_desc { @@ -189,6 +188,8 @@ struct sm_session { #define MAX_SESSIONS 32 struct sm_session_table { struct list_head next_table; + wait_queue_head_t query_wait; + uint32_t query_status; struct mutex lock; uint32_t nfree; uint32_t session_mask;
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
