/** arch/arm/mach-msm/smd_rpcrouter.h * * Copyright (C) 2007 Google, Inc. * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved. * Author: San Mehat * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H #define _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H #include #include #include #include #include #include #include /* definitions for the R2R wire protcol */ #define RPCROUTER_VERSION 1 #define RPCROUTER_PROCESSORS_MAX 4 #define RPCROUTER_MSGSIZE_MAX 512 #define RPCROUTER_PEND_REPLIES_MAX 32 #define RPCROUTER_CLIENT_BCAST_ID 0xffffffff #define RPCROUTER_ROUTER_ADDRESS 0xfffffffe #define RPCROUTER_PID_LOCAL 1 #define RPCROUTER_CTRL_CMD_DATA 1 #define RPCROUTER_CTRL_CMD_HELLO 2 #define RPCROUTER_CTRL_CMD_BYE 3 #define RPCROUTER_CTRL_CMD_NEW_SERVER 4 #define RPCROUTER_CTRL_CMD_REMOVE_SERVER 5 #define RPCROUTER_CTRL_CMD_REMOVE_CLIENT 6 #define RPCROUTER_CTRL_CMD_RESUME_TX 7 #define RPCROUTER_CTRL_CMD_EXIT 8 #define RPCROUTER_CTRL_CMD_PING 9 #define RPCROUTER_DEFAULT_RX_QUOTA 5 #define RPCROUTER_XPRT_EVENT_DATA 1 #define RPCROUTER_XPRT_EVENT_OPEN 2 #define RPCROUTER_XPRT_EVENT_CLOSE 3 /* Restart states for endpoint. * * Two different bits are specified here, one for * the remote server notification (RESTART_PEND_SVR) * and one for client notification (RESTART_PEND_NTFY). * The client notification is used to ensure that * the client gets notified by an ENETRESET return * code at least once, even if they miss the actual * reset event. The server notification is used to * properly handle the reset state of the endpoint. */ #define RESTART_NORMAL 0x0 #define RESTART_PEND_SVR 0x1 #define RESTART_PEND_NTFY 0x2 #define RESTART_PEND_NTFY_SVR (RESTART_PEND_SVR | RESTART_PEND_NTFY) union rr_control_msg { uint32_t cmd; struct { uint32_t cmd; uint32_t prog; uint32_t vers; uint32_t pid; uint32_t cid; } srv; struct { uint32_t cmd; uint32_t pid; uint32_t cid; } cli; }; struct rr_header { uint32_t version; uint32_t type; uint32_t src_pid; uint32_t src_cid; uint32_t confirm_rx; uint32_t size; uint32_t dst_pid; uint32_t dst_cid; }; /* internals */ #define RPCROUTER_MAX_REMOTE_SERVERS 100 struct rr_fragment { unsigned char data[RPCROUTER_MSGSIZE_MAX]; uint32_t length; struct rr_fragment *next; }; struct rr_packet { struct list_head list; struct rr_fragment *first; struct rr_fragment *last; struct rr_header hdr; uint32_t mid; uint32_t length; }; #define PACMARK_LAST(n) ((n) & 0x80000000) #define PACMARK_MID(n) (((n) >> 16) & 0xFF) #define PACMARK_LEN(n) ((n) & 0xFFFF) static inline uint32_t PACMARK(uint32_t len, uint32_t mid, uint32_t first, uint32_t last) { return (len & 0xFFFF) | ((mid & 0xFF) << 16) | ((!!first) << 30) | ((!!last) << 31); } struct rr_server { struct list_head list; uint32_t pid; uint32_t cid; uint32_t prog; uint32_t vers; dev_t device_number; struct cdev cdev; struct device *device; struct rpcsvr_platform_device p_device; char pdev_name[32]; }; struct rr_remote_endpoint { uint32_t pid; uint32_t cid; int tx_quota_cntr; int quota_restart_state; spinlock_t quota_lock; wait_queue_head_t quota_wait; struct list_head list; }; struct msm_rpc_reply { struct list_head list; uint32_t pid; uint32_t cid; uint32_t prog; /* be32 */ uint32_t vers; /* be32 */ uint32_t xid; /* be32 */ }; struct msm_rpc_endpoint { struct list_head list; /* incomplete packets waiting for assembly */ struct list_head incomplete; spinlock_t incomplete_lock; /* complete packets waiting to be read */ struct list_head read_q; spinlock_t read_q_lock; struct wake_lock read_q_wake_lock; wait_queue_head_t wait_q; unsigned flags; uint32_t forced_wakeup; /* restart handling */ int restart_state; spinlock_t restart_lock; wait_queue_head_t restart_wait; /* modem restart notifications */ int do_setup_notif; void *client_data; void (*cb_restart_teardown)(void *client_data); void (*cb_restart_setup)(void *client_data); /* endpoint address */ uint32_t pid; uint32_t cid; /* bound remote address * if not connected (dst_pid == 0xffffffff) RPC_CALL writes fail * RPC_CALLs must be to the prog/vers below or they will fail */ uint32_t dst_pid; uint32_t dst_cid; uint32_t dst_prog; /* be32 */ uint32_t dst_vers; /* be32 */ /* reply queue for inbound messages */ struct list_head reply_pend_q; struct list_head reply_avail_q; spinlock_t reply_q_lock; uint32_t reply_cnt; struct wake_lock reply_q_wake_lock; /* device node if this endpoint is accessed via userspace */ dev_t dev; }; enum write_data_type { HEADER = 1, PACKMARK, PAYLOAD, }; struct rpcrouter_xprt { char *name; void *priv; int (*read_avail)(void); int (*read)(void *data, uint32_t len); int (*write_avail)(void); int (*write)(void *data, uint32_t len, enum write_data_type type); int (*close)(void); }; /* shared between smd_rpcrouter*.c */ void msm_rpcrouter_xprt_notify(struct rpcrouter_xprt *xprt, unsigned event); int __msm_rpc_read(struct msm_rpc_endpoint *ept, struct rr_fragment **frag, unsigned len, long timeout); int msm_rpcrouter_close(void); struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev); int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept); int msm_rpcrouter_create_server_cdev(struct rr_server *server); int msm_rpcrouter_create_server_pdev(struct rr_server *server); int msm_rpcrouter_init_devices(void); void msm_rpcrouter_exit_devices(void); void get_requesting_client(struct msm_rpc_endpoint *ept, uint32_t xid, struct msm_rpc_client_info *clnt_info); extern dev_t msm_rpcrouter_devno; extern struct completion rpc_remote_router_up; extern struct class *msm_rpcrouter_class; void xdr_init(struct msm_rpc_xdr *xdr); void xdr_init_input(struct msm_rpc_xdr *xdr, void *buf, uint32_t size); void xdr_init_output(struct msm_rpc_xdr *xdr, void *buf, uint32_t size); void xdr_clean_input(struct msm_rpc_xdr *xdr); void xdr_clean_output(struct msm_rpc_xdr *xdr); uint32_t xdr_read_avail(struct msm_rpc_xdr *xdr); #endif