[Feature][ZXW-88]merge P50 version

Only Configure: No
Affected branch: master
Affected module: unknown
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I34667719d9e0e7e29e8e4368848601cde0a48408
diff --git a/ap/os/linux/linux-3.4.x/include/linux/fs.h b/ap/os/linux/linux-3.4.x/include/linux/fs.h
old mode 100644
new mode 100755
index 210c347..463df11
--- a/ap/os/linux/linux-3.4.x/include/linux/fs.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/fs.h
@@ -1021,6 +1021,9 @@
 #ifdef CONFIG_DEBUG_WRITECOUNT
 	unsigned long f_mnt_write_state;
 #endif
+#ifdef CONFIG_SYSVIPC_CROSS_SHM
+	unsigned int 	shm_flags;
+#endif
 };
 
 struct file_handle {
diff --git a/ap/os/linux/linux-3.4.x/include/linux/net.h b/ap/os/linux/linux-3.4.x/include/linux/net.h
old mode 100644
new mode 100755
index 16b4996..f323b7d
--- a/ap/os/linux/linux-3.4.x/include/linux/net.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/net.h
@@ -148,6 +148,10 @@
 	struct socket_wq __rcu	*wq;
 
 	struct file		*file;
+#ifdef CONFIG_IPC_SOCKET
+	int fd;
+	struct hlist_head peer;
+#endif
 	struct sock		*sk;
 	const struct proto_ops	*ops;
 };
diff --git a/ap/os/linux/linux-3.4.x/include/linux/socket.h b/ap/os/linux/linux-3.4.x/include/linux/socket.h
old mode 100644
new mode 100755
index 9b54ebe..cc1afdc
--- a/ap/os/linux/linux-3.4.x/include/linux/socket.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/socket.h
@@ -343,5 +343,6 @@
 			  unsigned int flags, struct timespec *timeout);
 extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
 			  unsigned int vlen, unsigned int flags);
+
 #endif /* not kernel and not glibc */
 #endif /* _LINUX_SOCKET_H */
diff --git a/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
new file mode 100755
index 0000000..c6a9292
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
@@ -0,0 +1,227 @@
+#ifndef SOCKET_RPMSG_H

+#define SOCKET_RPMSG_H

+

+#include <linux/interrupt.h>

+#include <linux/kthread.h>

+#include <linux/spinlock.h>

+#include <linux/semaphore.h>

+#include <linux/netdevice.h>

+#include <linux/skbuff.h>

+#include <linux/un.h>

+#include <linux/types.h>

+#include <linux/soc/zte/rpm/rpmsg.h>

+

+#include <net/sock.h>

+

+extern int socket_rpmsg_debug;

+

+#define sk_soc_dbg(format, arg...) if(socket_rpmsg_debug == 1) \

+	printk(KERN_DEBUG "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)

+#define sk_soc_info(format, arg...) if(socket_rpmsg_debug == 1) \

+	printk(KERN_INFO "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)

+

+#define sk_soc_err(format, arg...) printk(KERN_ERR "[socket_rpmsg]<%s>: " format "\n" , \

+	__func__ , ## arg)

+

+#define sk_soc_warn(format, arg...) printk(KERN_WARNING "[socket_rpmsg]<%s>: " format "\n" , \

+	__func__ , ## arg)

+

+

+

+#define	 ICP_CHANNEL_SIZE 	(16 * 1024)

+

+/*remote data ,to local,read from rpmsg channel*/

+#define DIR_UPLINK		1

+/*local data ,to remote,need write rpmsg channel*/

+#define DIR_DOWNLINK	2

+#define sockSocCreateChannel zDrvRpMsg_CreateChannel_Cap

+#define sockSocWrite         zDrvRpMsg_Write_Cap

+#define sockSocRead          zDrvRpMsg_Read_Cap

+

+#define SOCK_OP_RESULT		0

+

+extern spinlock_t sock_table_lock;

+extern spinlock_t sock_rpmsg_table_lock;

+extern spinlock_t sock_socket_table_lock;

+extern spinlock_t sock_release_table_lock;

+extern spinlock_t sock_release_lock;

+extern spinlock_t  sock_release_peer_lock;

+typedef enum _soc_msg_type

+{

+	MSG_TYPE_FIND = 0,

+	MSG_TYPE_FIND_RESULT,

+	MSG_TYPE_ADD_WAIT_QUEUE,

+	MSG_TYPE_REMOVE_WAIT_QUEUE,

+	MSG_TYPE_SYNC_IPC_SOCKET,

+	MSG_TYPE_WAIT_FOR_PEER,

+	MSG_TYPE_DATA_READY,

+	MSG_TYPE_SEND_MSG,

+	MSG_TYPE_SET_PEER,

+	MSG_TYPE_UPDATE_PEER,

+	MSG_TYPE_SOCK_PUT,

+	MSG_TYPE_ADD_SKB_QUEUE_TAIL,

+	MSG_TYPE_RECVQ_FULL,

+	MSG_TYPE_RECVQ_FULL_RESULT,

+	MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD,

+	MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD_RESULT,

+	MSG_TYPE_PEER_CLEAR,

+	MSG_TYPE_WAKE_UP_INTERRUPTIBLE_POLL,

+	MSG_TYPE_TEST_FLAG,

+	MSG_TYPE_TEST_FLAG_RESULT,

+	MSG_TYPE_GET_SOCKET_STATES,

+	MSG_TYPE_GET_SOCKET_STATES_RESULT,

+	MSG_TYPE_STREAM_CONNECT, //21

+	MSG_TYPE_SOCKET_RELEASE, //22

+	MSG_TYPE_DGRAM_DISCONNECTED,

+	MSG_TYPE_STATE_LOCK,

+	MSG_TYPE_STATE_UNLOCK,

+	MSG_TYPE_SOCK_HOLD,

+	MSG_TYPE_RELEASE_PEER,

+	MSG_TYPE_NOTIFY_PROXY_CHANGE,

+}soc_msg_type;

+

+struct sock_thread_info {

+	struct task_struct *p_thread;	

+	struct list_head	p_sock_list;

+	struct spinlock 	p_sock_lock;

+	struct semaphore 	p_sock_sem;

+

+	int bstop;

+};

+

+struct sock_channel {

+    T_ZDrvRpMsg_ActorID core_id;

+    T_ZDrvRpMsg_ChID channel_id;

+    unsigned int channel_size;

+    //struct task_struct *rcv_thread;

+	//struct task_struct *main_thread;

+	struct sock_thread_info recv_thread_info;

+	struct sock_thread_info main_thread_info;

+};

+

+struct sock_elem_flag {

+	int sk_err;

+	int sk_error_report;

+	int skstate;

+	u8 skshutdown;

+};

+

+struct	sock_rpmsg

+{

+	struct list_head list;

+	soc_msg_type msg_type;

+	uint32_t dir;

+	struct sockaddr_un sockaddr;

+	int addr_len;

+	int socktype; 

+	unsigned int hash;

+	struct sock_elem_flag elem;

+	//struct sock sock;	

+	int clientfd;

+	int serverfd;

+	int clientproxyfd;

+	int serverproxyfd;

+	int newclientfd;

+	void* clientsock; //ÀàÐÍΪstruct socket

+	void* serversock; //ÀàÐÍΪstruct socket

+	void* newsock;

+	void* clientproxysock; //ÀàÐÍΪstruct socket

+	void* serverproxysock; //ÀàÐÍΪstruct socket

+	int result;

+	enum sock_flags flag;

+	unsigned long flags;

+	long timeo;

+	unsigned int  msg_flags;

+	int isfistfind;

+	void* key;

+	unsigned int index;

+	int data_len;

+	unsigned char data[0];	

+};

+

+struct	ipc_socket

+{	

+	struct hlist_node	hlist_node;

+	struct socket* socket;

+	struct sock* sock;

+	int socktype; 

+	int localfd;  //±¾µØ¿Í»§¶Ëfd

+	int sockfd;   //±¾µØ´úÀísocketµÄfd

+	int remotefd; //¶ÔÓ¦Ô¶¶ËʵÌåµÄfd

+	int remoteproxyfd; //¶ÔÓ¦Ô¶¶Ë´úÀíµÄ fd

+	struct socket* localsocket; //±¾µØ¿Í»§¶Ësocket

+	struct socket* proxysocket; //±¾µØ´úÀísocket

+	struct socket* remotesocket; //¶ÔÓ¦Ô¶¶ËʵÌåµÄsocket

+	struct socket* remoteproxysocket; //¶ÔÓ¦Ô¶¶Ë´úÀíµÄsocket

+	void* key;

+};

+

+struct sock_rpmsg_info

+{

+	struct hlist_node	hlist_node;

+	struct sock_rpmsg sock_rpmsg;

+	struct semaphore sock_sem;

+	struct ipc_socket * ipc_socket;

+	void* key; //±êʶrpmsgµÄ¹Ø¼ü×Ö

+};

+

+struct	peer_sock_info

+{	

+	int fd;

+	int peerfd;

+	struct sock* sock;

+	struct sock* peersock;

+	long timeo;

+};

+

+struct release_socket{

+	struct list_head	list_node;

+#if 0	

+	struct socket* sock;

+	int clientfd;

+	void* clientsock;

+#endif	

+	int localfd; //¿Í»§¶Ëfd

+	int proxyfd;   //±¾µØ´úÀísocketµÄfd

+	int remotefd; //¶ÔÓ¦Ô¶¶ËʵÌåµÄfd

+	struct socket* localsocket; //±¾µØ¿Í»§¶Ësocket

+	struct socket* proxysocket; //±¾µØ´úÀísocket

+	struct socket* remotesocket; //¶ÔÓ¦Ô¶¶ËʵÌåµÄsocket

+	struct socket* remoteproxysocket; //¶ÔÓ¦´úÀíµÄsocket

+};

+

+//´æ·ÅËùÓвÎÓë½»»¥µÄsocketµØÖ·

+struct socket_info{

+	struct hlist_node	hlist_node;

+	struct socket* proxysocket;

+	struct socket* localsocket;

+};

+

+int sock_soc_recvq_full(const struct sock *sk);

+int sock_soc_set_peer(struct sock *sock, struct sock *other);

+int sock_soc_sock_put(struct sock *other);

+int sock_soc_msg_send(struct sock *sock, struct sock *other, struct msghdr *msg, size_t len);

+long sock_wait_for_peer(struct sock *sock, struct sock *other, long timeo);

+int sock_soc_sk_data_ready(struct sock *sk);

+int sock_sync_ipc_socket(struct sock_elem_flag* elem_flag, struct sock *other);

+void sock_soc_add_skb_queue_tail(struct sock *sock, struct sock *other);

+void sock_soc_add_wait_queue(struct sock *sock, struct sock *other);

+void sock_soc_remove_wait_queue(struct sock *sock, struct sock *other);

+struct sock *sock_soc_find_other(struct socket* socket,

+				    struct sockaddr_un *sunname, int len,

+				    int type, unsigned int hash, int *error);

+int unix_is_ipc_socket(struct sock *sock);

+int unix_is_ipc_local_socket(struct sock *sock);

+int sock_soc_test_flags(struct sock *other, enum sock_flags flag);

+int sock_soc_recvq_full_lockless_and_dead(const struct sock *other);

+int sock_soc_get_state(struct sock_elem_flag* elem_flag, struct sock *other);

+void sock_soc_stream_connect(struct sock *sock, struct sock *other, struct sockaddr_un *sunname, int len,int flags);

+int sock_soc_update_peer(struct socket *sock, struct socket *newsock);

+int sock_soc_dgram_disconnected(struct sock *sock, struct sock *other);

+void sock_soc_state_lock(struct sock *other);

+void sock_soc_state_unlock(struct sock *other);

+void sock_soc_delay_release(struct socket *sock);

+void sock_soc_sock_hold(struct sock *other);

+

+#endif

+

diff --git a/ap/os/linux/linux-3.4.x/include/net/af_unix.h b/ap/os/linux/linux-3.4.x/include/net/af_unix.h
old mode 100644
new mode 100755
index ca68e2c..d997e45
--- a/ap/os/linux/linux-3.4.x/include/net/af_unix.h
+++ b/ap/os/linux/linux-3.4.x/include/net/af_unix.h
@@ -5,6 +5,9 @@
 #include <linux/un.h>
 #include <linux/mutex.h>
 #include <net/sock.h>
+#ifdef CONFIG_IPC_SOCKET
+#include <linux/socket_rpmsg.h>
+#endif
 
 extern void unix_inflight(struct file *fp);
 extern void unix_notinflight(struct file *fp);
@@ -60,6 +63,9 @@
 	unsigned int		gc_maybe_cycle : 1;
 	unsigned char		recursion_level;
 	struct socket_wq	peer_wq;
+#ifdef CONFIG_IPC_SOCKET
+	struct release_socket rsock;
+#endif	
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
 
diff --git a/ap/os/linux/linux-3.4.x/include/net/sock.h b/ap/os/linux/linux-3.4.x/include/net/sock.h
index efab120..7f2098b 100755
--- a/ap/os/linux/linux-3.4.x/include/net/sock.h
+++ b/ap/os/linux/linux-3.4.x/include/net/sock.h
@@ -85,6 +85,16 @@
 {
 }
 #endif
+
+#ifdef CONFIG_IPC_SOCKET
+extern int socket_rpmsg_debug;
+
+#define sk_soc_dbg(format, arg...) if(socket_rpmsg_debug == 1) \
+	printk(KERN_DEBUG "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+#define sk_soc_info(format, arg...) if(socket_rpmsg_debug == 1) \
+	printk(KERN_INFO "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+
+#endif
 /*
  * This structure really needs to be cleaned up.
  * Most of it is for TCP, and not used by any of
@@ -127,6 +137,15 @@
 struct proto;
 struct net;
 
+#ifdef CONFIG_IPC_SOCKET
+
+enum sock_flags;
+extern int unix_is_ipc_socket(struct sock *sock);
+extern int sock_soc_test_flags(struct sock *other, enum sock_flags flag);
+extern int sock_soc_sock_put(struct sock *other);
+extern void sock_soc_sock_hold(struct sock *other);
+
+#endif
 /**
  *	struct sock_common - minimal network layer representation of sockets
  *	@skc_daddr: Foreign IPv4 addr
@@ -382,6 +401,12 @@
   	int			(*sk_backlog_rcv)(struct sock *sk,
 						  struct sk_buff *skb);  
 	void                    (*sk_destruct)(struct sock *sk);
+#ifdef CONFIG_IPC_SOCKET
+	int ipc_flag;
+	int sk_fd;
+	struct sock* proxy_sock;
+	u8 closed;
+#endif	
 };
 
 static inline int sk_peek_offset(struct sock *sk, int flags)
@@ -495,6 +520,9 @@
 static inline void sock_hold(struct sock *sk)
 {
 	atomic_inc(&sk->sk_refcnt);
+#ifdef CONFIG_IPC_SOCKET
+    sk_soc_dbg("sock_hold sk=%x, sk->sk_refcnt=%d\n", sk, sk->sk_refcnt);
+#endif	
 }
 
 /* Ungrab socket in the context, which assumes that socket refcnt
@@ -502,6 +530,9 @@
  */
 static inline void __sock_put(struct sock *sk)
 {
+#ifdef CONFIG_IPC_SOCKET	
+	sk_soc_dbg("__sock_put sk=%x, sk->sk_refcnt=%d\n",sk, sk->sk_refcnt);
+#endif	
 	atomic_dec(&sk->sk_refcnt);
 }
 
@@ -629,6 +660,10 @@
 		     * Will use last 4 bytes of packet sent from
 		     * user-space instead.
 		     */
+#ifdef CONFIG_IPC_SOCKET
+    SOCK_IPCSOCK,  /*Indicates whether it is a cross core socket */
+    SOCK_IPC_LOCAL,
+#endif
 };
 
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -648,7 +683,16 @@
 
 static inline int sock_flag(struct sock *sk, enum sock_flags flag)
 {
+#ifdef CONFIG_IPC_SOCKET
+	if(unix_is_ipc_socket(sk)){
+		return sock_soc_test_flags(sk, flag);
+	}
+	else{
+#endif
 	return test_bit(flag, &sk->sk_flags);
+#ifdef CONFIG_IPC_SOCKET
+	}
+#endif
 }
 
 static inline void sk_acceptq_removed(struct sock *sk)
@@ -1586,7 +1630,10 @@
 }
 
 static inline void sk_set_socket(struct sock *sk, struct socket *sock)
-{
+{	
+#ifdef CONFIG_IPC_SOCKET	
+	sk_soc_dbg("sk_set_socket sk=%x, sock=%x \n", sk, sock);
+#endif	
 	sk_tx_queue_clear(sk);
 	sk->sk_socket = sock;
 }