blob: 1da7579aef89cd9ad2635bb0fec99815d1559611 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/** arch/arm/mach-msm/smd_rpcrouter.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
5 * Author: San Mehat <san@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H
19#define _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H
20
21#include <linux/types.h>
22#include <linux/list.h>
23#include <linux/cdev.h>
24#include <linux/platform_device.h>
25#include <linux/msm_rpcrouter.h>
26#include <linux/wakelock.h>
27
28#include <mach/msm_smd.h>
29#include <mach/msm_rpcrouter.h>
30
31/* definitions for the R2R wire protcol */
32
33#define RPCROUTER_VERSION 1
34#define RPCROUTER_PROCESSORS_MAX 4
35#define RPCROUTER_MSGSIZE_MAX 512
36#define RPCROUTER_PEND_REPLIES_MAX 32
37
38#define RPCROUTER_CLIENT_BCAST_ID 0xffffffff
39#define RPCROUTER_ROUTER_ADDRESS 0xfffffffe
40
41#define RPCROUTER_PID_LOCAL 1
42
43#define RPCROUTER_CTRL_CMD_DATA 1
44#define RPCROUTER_CTRL_CMD_HELLO 2
45#define RPCROUTER_CTRL_CMD_BYE 3
46#define RPCROUTER_CTRL_CMD_NEW_SERVER 4
47#define RPCROUTER_CTRL_CMD_REMOVE_SERVER 5
48#define RPCROUTER_CTRL_CMD_REMOVE_CLIENT 6
49#define RPCROUTER_CTRL_CMD_RESUME_TX 7
50#define RPCROUTER_CTRL_CMD_EXIT 8
51#define RPCROUTER_CTRL_CMD_PING 9
52
53#define RPCROUTER_DEFAULT_RX_QUOTA 5
54
55#define RPCROUTER_XPRT_EVENT_DATA 1
56#define RPCROUTER_XPRT_EVENT_OPEN 2
57#define RPCROUTER_XPRT_EVENT_CLOSE 3
58
59/* Restart states for endpoint.
60 *
61 * Two different bits are specified here, one for
62 * the remote server notification (RESTART_PEND_SVR)
63 * and one for client notification (RESTART_PEND_NTFY).
64 * The client notification is used to ensure that
65 * the client gets notified by an ENETRESET return
66 * code at least once, even if they miss the actual
67 * reset event. The server notification is used to
68 * properly handle the reset state of the endpoint.
69 */
70#define RESTART_NORMAL 0x0
71#define RESTART_PEND_SVR 0x1
72#define RESTART_PEND_NTFY 0x2
73#define RESTART_PEND_NTFY_SVR (RESTART_PEND_SVR | RESTART_PEND_NTFY)
74
75union rr_control_msg {
76 uint32_t cmd;
77 struct {
78 uint32_t cmd;
79 uint32_t prog;
80 uint32_t vers;
81 uint32_t pid;
82 uint32_t cid;
83 } srv;
84 struct {
85 uint32_t cmd;
86 uint32_t pid;
87 uint32_t cid;
88 } cli;
89};
90
91struct rr_header {
92 uint32_t version;
93 uint32_t type;
94 uint32_t src_pid;
95 uint32_t src_cid;
96 uint32_t confirm_rx;
97 uint32_t size;
98 uint32_t dst_pid;
99 uint32_t dst_cid;
100};
101
102/* internals */
103
104#define RPCROUTER_MAX_REMOTE_SERVERS 100
105
106struct rr_fragment {
107 unsigned char data[RPCROUTER_MSGSIZE_MAX];
108 uint32_t length;
109 struct rr_fragment *next;
110};
111
112struct rr_packet {
113 struct list_head list;
114 struct rr_fragment *first;
115 struct rr_fragment *last;
116 struct rr_header hdr;
117 uint32_t mid;
118 uint32_t length;
119};
120
121#define PACMARK_LAST(n) ((n) & 0x80000000)
122#define PACMARK_MID(n) (((n) >> 16) & 0xFF)
123#define PACMARK_LEN(n) ((n) & 0xFFFF)
124
125static inline uint32_t PACMARK(uint32_t len, uint32_t mid, uint32_t first,
126 uint32_t last)
127{
128 return (len & 0xFFFF) |
129 ((mid & 0xFF) << 16) |
130 ((!!first) << 30) |
131 ((!!last) << 31);
132}
133
134struct rr_server {
135 struct list_head list;
136
137 uint32_t pid;
138 uint32_t cid;
139 uint32_t prog;
140 uint32_t vers;
141
142 dev_t device_number;
143 struct cdev cdev;
144 struct device *device;
145 struct rpcsvr_platform_device p_device;
146 char pdev_name[32];
147};
148
149struct rr_remote_endpoint {
150 uint32_t pid;
151 uint32_t cid;
152
153 int tx_quota_cntr;
154 int quota_restart_state;
155 spinlock_t quota_lock;
156 wait_queue_head_t quota_wait;
157
158 struct list_head list;
159};
160
161struct msm_rpc_reply {
162 struct list_head list;
163 uint32_t pid;
164 uint32_t cid;
165 uint32_t prog; /* be32 */
166 uint32_t vers; /* be32 */
167 uint32_t xid; /* be32 */
168};
169
170struct msm_rpc_endpoint {
171 struct list_head list;
172
173 /* incomplete packets waiting for assembly */
174 struct list_head incomplete;
175 spinlock_t incomplete_lock;
176
177 /* complete packets waiting to be read */
178 struct list_head read_q;
179 spinlock_t read_q_lock;
180 struct wake_lock read_q_wake_lock;
181 wait_queue_head_t wait_q;
182 unsigned flags;
183 uint32_t forced_wakeup;
184
185 /* restart handling */
186 int restart_state;
187 spinlock_t restart_lock;
188 wait_queue_head_t restart_wait;
189
190 /* modem restart notifications */
191 int do_setup_notif;
192 void *client_data;
193 void (*cb_restart_teardown)(void *client_data);
194 void (*cb_restart_setup)(void *client_data);
195
196 /* endpoint address */
197 uint32_t pid;
198 uint32_t cid;
199
200 /* bound remote address
201 * if not connected (dst_pid == 0xffffffff) RPC_CALL writes fail
202 * RPC_CALLs must be to the prog/vers below or they will fail
203 */
204 uint32_t dst_pid;
205 uint32_t dst_cid;
206 uint32_t dst_prog; /* be32 */
207 uint32_t dst_vers; /* be32 */
208
209 /* reply queue for inbound messages */
210 struct list_head reply_pend_q;
211 struct list_head reply_avail_q;
212 spinlock_t reply_q_lock;
213 uint32_t reply_cnt;
214 struct wake_lock reply_q_wake_lock;
215
216 /* device node if this endpoint is accessed via userspace */
217 dev_t dev;
218};
219
220enum write_data_type {
221 HEADER = 1,
222 PACKMARK,
223 PAYLOAD,
224};
225
226struct rpcrouter_xprt {
227 char *name;
228 void *priv;
229
230 int (*read_avail)(void);
231 int (*read)(void *data, uint32_t len);
232 int (*write_avail)(void);
233 int (*write)(void *data, uint32_t len, enum write_data_type type);
234 int (*close)(void);
235};
236
237/* shared between smd_rpcrouter*.c */
238void msm_rpcrouter_xprt_notify(struct rpcrouter_xprt *xprt, unsigned event);
239int __msm_rpc_read(struct msm_rpc_endpoint *ept,
240 struct rr_fragment **frag,
241 unsigned len, long timeout);
242
243int msm_rpcrouter_close(void);
244struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev);
245int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept);
246
247int msm_rpcrouter_create_server_cdev(struct rr_server *server);
248int msm_rpcrouter_create_server_pdev(struct rr_server *server);
249
250int msm_rpcrouter_init_devices(void);
251void msm_rpcrouter_exit_devices(void);
252
253void get_requesting_client(struct msm_rpc_endpoint *ept, uint32_t xid,
254 struct msm_rpc_client_info *clnt_info);
255
256extern dev_t msm_rpcrouter_devno;
257extern struct completion rpc_remote_router_up;
258extern struct class *msm_rpcrouter_class;
259
260void xdr_init(struct msm_rpc_xdr *xdr);
261void xdr_init_input(struct msm_rpc_xdr *xdr, void *buf, uint32_t size);
262void xdr_init_output(struct msm_rpc_xdr *xdr, void *buf, uint32_t size);
263void xdr_clean_input(struct msm_rpc_xdr *xdr);
264void xdr_clean_output(struct msm_rpc_xdr *xdr);
265uint32_t xdr_read_avail(struct msm_rpc_xdr *xdr);
266#endif