commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=f715962a27497792d63a91c84b285b5337e1cea1
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 |   66 +++++++++++++++++++++++++++++++++-
 drivers/staging/icc/include/icc.h   |    8 +++-
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/icc/core/protocol.c b/drivers/staging/icc/core/protocol.c
index 54f0634..599aa6a 100644
--- a/drivers/staging/icc/core/protocol.c
+++ b/drivers/staging/icc/core/protocol.c
@@ -722,6 +722,25 @@ 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,
+		uint32_t dst_cpu)
+{
+	struct sm_session *session;
+	session = sm_index_to_session(session_idx);
+	if (!session)
+		return -EINVAL;
+
+	mutex_lock(&bfin_icc->sessions_table->lock);
+	session->flags = SM_QUERY;
+	mutex_unlock(&bfin_icc->sessions_table->lock);
+	sm_send_control_msg(session, dst_ep, dst_cpu, 0,
+				0, SM_QUERY_MSG);
+	wait_event_interruptible_timeout(session->rx_wait,
+				(session->flags == 0), HZ);
+	sm_debug("received query ack\n");
+	return 0;
+}
+
 static int
 sm_wait_for_connect_ack(struct sm_session *session)
 {
@@ -1100,6 +1119,9 @@ icc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case CMD_SM_RELEASE_UNCACHED_BUF:
 		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);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1429,6 +1451,47 @@ struct sm_proto session_scalar_proto = {
 	.error = sm_default_error,
 };
 
+int __handle_general_msg(struct sm_msg *msg)
+{
+	int index;
+	struct sm_session *session;
+	struct sm_icc_desc *icc_info;
+	int ret = 0;
+
+	switch (msg->type) {
+	case SM_BAD_MSG:
+		printk(KERN_WARNING "%s", (char *)msg->payload);
+		ret = 1;
+		break;
+	case SM_QUERY_MSG:
+		index = sm_find_session(msg->dst_ep, 0, bfin_icc->sessions_table);
+		session = sm_index_to_session(index);
+
+		if (session) {
+			icc_info = get_icc_peer(msg);
+			sm_send_control_msg(session, msg->src_ep,
+				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;
+		}
+	default:
+		ret = 0;
+	}
+
+	return ret;
+}
+
 int __msg_handle(struct sm_icc_desc *icc_info, struct sm_message_queue *inqueue)
 {
 	uint16_t received = sm_atomic_read(&inqueue->received);
@@ -1447,8 +1510,7 @@ int __msg_handle(struct sm_icc_desc *icc_info, struct sm_message_queue *inqueue)
 
 	msg = &inqueue->messages[(received % SM_MSGQ_LEN)];
 
-	if (msg->type == SM_BAD_MSG) {
-		printk(KERN_WARNING "%s", (char *)msg->payload);
+	if (__handle_general_msg(msg)) {
 		sm_message_dequeue(msg);
 		return 1;
 	}
diff --git a/drivers/staging/icc/include/icc.h b/drivers/staging/icc/include/icc.h
index 145a276..410a6c5 100644
--- a/drivers/staging/icc/include/icc.h
+++ b/drivers/staging/icc/include/icc.h
@@ -43,9 +43,12 @@ enum {
 #define SM_CONNECTING 0x2
 #define SM_OPEN 0x4
 #define SM_ACTIVE 0x8
+#define SM_QUERY 0x10
 
-#define SM_BAD_ENDPOINT SM_MSG_TYPE(0, 0)
-#define SM_BAD_MSG SM_MSG_TYPE(0, 1)
+#define SM_BAD_ENDPOINT SM_MSG_TYPE(SP_GENERAL, 0)
+#define SM_BAD_MSG SM_MSG_TYPE(SP_GENERAL, 1)
+#define SM_QUERY_MSG SM_MSG_TYPE(SP_GENERAL, 2)
+#define SM_QUERY_ACK_MSG SM_MSG_TYPE(SP_GENERAL, 3)
 
 #define SM_CORE_START		SM_MSG_TYPE(SP_CORE_CONTROL, 0)
 #define SM_CORE_STARTED		SM_MSG_TYPE(SP_CORE_CONTROL, 1)
@@ -219,6 +222,7 @@ struct sm_proto {
 #define CMD_SM_ACTIVE _IO('m', 12)
 #define CMD_SM_REQUEST_UNCACHED_BUF _IO('m', 13)
 #define CMD_SM_RELEASE_UNCACHED_BUF _IO('m', 14)
+#define CMD_SM_QUERY_REMOTE_EP	_IO('m', 15)
 
 #define MAX_TASK_NAME 64
 struct sm_node_status {
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to