aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2014-08-29 15:38:44 -0500
committerSuman Anna2014-08-29 15:39:16 -0500
commita6a650e0e517fc1881525cdb15013836a9821a2d (patch)
treebb018a66be00d607526bfd186d904abc28834ab1
parent951dbd6f870731f2431645604a768718fce182b8 (diff)
parent1d987626bd652ce5cc798fbf1383670bfb587871 (diff)
downloadkernel-video-a6a650e0e517fc1881525cdb15013836a9821a2d.tar.gz
kernel-video-a6a650e0e517fc1881525cdb15013836a9821a2d.tar.xz
kernel-video-a6a650e0e517fc1881525cdb15013836a9821a2d.zip
Merge branch 'rpmsg-linux-3.14.y' of git://git.ti.com/rpmsg/rpmsg into rpmsg-ti-linux-3.14.y
Pull in the base rpmsg tree that adds two new rpmsg client drivers: rpmsg-rpc & rpmsg-proto. The rpmsg-rpc driver is currently used with the MultiMedia stack, and needs a patch in omapdrm for proper cache flushing of the pages where the rpc pointer translations are being handled. The rpmsg-proto driver supports the MessageQ API in the IPC product * 'rpmsg-linux-3.14.y' of git://git.ti.com/rpmsg/rpmsg: net/rpmsg: add support for new rpmsg sockets rpmsg: add api for creating and deleting rpmsg channels drm/omap: flush the mapped page in kmap/kunmap rpmsg: rpc: introduce a new rpmsg_rpc driver rpmsg: add api for getting the underlying virtio device Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c19
-rw-r--r--drivers/rpmsg/Kconfig15
-rw-r--r--drivers/rpmsg/Makefile3
-rw-r--r--drivers/rpmsg/rpmsg_rpc.c1389
-rw-r--r--drivers/rpmsg/rpmsg_rpc_dmabuf.c655
-rw-r--r--drivers/rpmsg/rpmsg_rpc_internal.h416
-rw-r--r--drivers/rpmsg/rpmsg_rpc_sysfs.c255
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c88
-rw-r--r--include/linux/rpmsg.h5
-rw-r--r--include/linux/rpmsg_rpc.h105
-rw-r--r--include/linux/socket.h5
-rw-r--r--include/uapi/linux/rpmsg_rpc.h208
-rw-r--r--include/uapi/linux/rpmsg_socket.h47
-rw-r--r--net/Makefile1
-rw-r--r--net/rpmsg/Makefile1
-rw-r--r--net/rpmsg/rpmsg_proto.c684
16 files changed, 3889 insertions, 7 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 4fcca8d4279..ded3d82e149 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -122,8 +122,18 @@ static void *omap_gem_dmabuf_kmap(struct dma_buf *buffer,
122{ 122{
123 struct drm_gem_object *obj = buffer->priv; 123 struct drm_gem_object *obj = buffer->priv;
124 struct page **pages; 124 struct page **pages;
125 dma_addr_t dma_addr;
125 omap_gem_get_pages(obj, &pages, false); 126 omap_gem_get_pages(obj, &pages, false);
126 omap_gem_cpu_sync(obj, page_num); 127 omap_gem_cpu_sync(obj, page_num);
128
129 /*
130 * invalidate/flush the cache for this page deliberately.
131 * XXX: revisit this, to find the proper place for invoking these calls.
132 */
133 dma_addr = dma_map_page(obj->dev->dev, pages[page_num], 0, PAGE_SIZE,
134 DMA_BIDIRECTIONAL);
135 dma_unmap_page(obj->dev->dev, dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
136
127 return kmap(pages[page_num]); 137 return kmap(pages[page_num]);
128} 138}
129 139
@@ -132,8 +142,17 @@ static void omap_gem_dmabuf_kunmap(struct dma_buf *buffer,
132{ 142{
133 struct drm_gem_object *obj = buffer->priv; 143 struct drm_gem_object *obj = buffer->priv;
134 struct page **pages; 144 struct page **pages;
145 dma_addr_t dma_addr;
135 omap_gem_get_pages(obj, &pages, false); 146 omap_gem_get_pages(obj, &pages, false);
136 kunmap(pages[page_num]); 147 kunmap(pages[page_num]);
148
149 /*
150 * invalidate/flush the cache for this page deliberately.
151 * XXX: revisit this, to find the proper place for invoking these calls.
152 */
153 dma_addr = dma_map_page(obj->dev->dev, pages[page_num], 0, PAGE_SIZE,
154 DMA_BIDIRECTIONAL);
155 dma_unmap_page(obj->dev->dev, dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
137} 156}
138 157
139static int omap_gem_dmabuf_mmap(struct dma_buf *buffer, 158static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 69a21938758..1b18619447d 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -6,4 +6,19 @@ config RPMSG
6 select VIRTIO 6 select VIRTIO
7 select VIRTUALIZATION 7 select VIRTUALIZATION
8 8
9config RPMSG_RPC
10 tristate "rpmsg Remote Procedure Call driver"
11 default n
12 depends on RPMSG
13 depends on REMOTEPROC
14 depends on OMAP_REMOTEPROC
15 select DMA_SHARED_BUFFER
16 ---help---
17 An rpmsg driver that exposes the Remote Procedure Call API to
18 user space, in order to allow applications to distribute
19 remote calls to more power-efficient remote processors. This is
20 currently available only on OMAP4+ systems.
21
22 If unsure, say N.
23
9endmenu 24endmenu
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 7617fcb8259..74c670366d3 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -1 +1,4 @@
1obj-$(CONFIG_RPMSG) += virtio_rpmsg_bus.o 1obj-$(CONFIG_RPMSG) += virtio_rpmsg_bus.o
2
3obj-$(CONFIG_RPMSG_RPC) += rpmsg-rpc.o
4rpmsg-rpc-y := rpmsg_rpc.o rpmsg_rpc_sysfs.o rpmsg_rpc_dmabuf.o
diff --git a/drivers/rpmsg/rpmsg_rpc.c b/drivers/rpmsg/rpmsg_rpc.c
new file mode 100644
index 00000000000..e5aeb4d446f
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_rpc.c
@@ -0,0 +1,1389 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Erik Rainey <erik.rainey@ti.com>
7 * Suman Anna <s-anna@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#define pr_fmt(fmt) "%s: " fmt, __func__
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/idr.h>
25#include <linux/poll.h>
26#include <linux/mutex.h>
27#include <linux/sched.h>
28#include <linux/fdtable.h>
29#include <linux/remoteproc.h>
30#include <linux/rpmsg.h>
31#include <linux/rpmsg_rpc.h>
32
33#include "rpmsg_rpc_internal.h"
34
35#define RPPC_MAX_DEVICES (8)
36#define RPPC_MAX_REG_FDS (10)
37
38#define RPPC_SIG_NUM_PARAM(sig) ((sig).num_param - 1)
39
40/* TODO: remove these fields */
41#define RPPC_JOBID_DISCRETE (0)
42#define RPPC_POOLID_DEFAULT (0x8000)
43
44static struct class *rppc_class;
45static dev_t rppc_dev;
46
47/* store all remote rpc connection services (usually one per remoteproc) */
48static DEFINE_IDR(rppc_devices);
49static DEFINE_MUTEX(rppc_devices_lock);
50
51/*
52 * Retrieve the rproc instance so that it can be used for performing
53 * address translations
54 */
55static struct rproc *rpdev_to_rproc(struct rpmsg_channel *rpdev)
56{
57 struct virtio_device *vdev;
58
59 vdev = rpmsg_get_virtio_dev(rpdev);
60 if (!vdev)
61 return NULL;
62
63 return rproc_vdev_to_rproc_safe(vdev);
64}
65
66/*
67 * A wrapper function to translate local physical addresses to the remote core
68 * device addresses (virtual addresses that a code on remote processor can use
69 * directly.
70 */
71phys_addr_t rppc_local_to_remote_da(struct rppc_instance *rpc, phys_addr_t pa)
72{
73 int ret;
74 struct rproc *rproc;
75 u64 da;
76 phys_addr_t rda;
77 struct device *dev = rpc->rppcdev->dev;
78
79 if (mutex_lock_interruptible(&rpc->rppcdev->lock))
80 return -EINTR;
81
82 rproc = rpdev_to_rproc(rpc->rppcdev->rpdev);
83 if (!rproc) {
84 dev_err(dev, "error getting rproc for rpdev 0x%x\n",
85 (u32)rpc->rppcdev->rpdev);
86 } else {
87 ret = rproc_pa_to_da(rproc, pa, &da);
88 if (ret) {
89 dev_err(dev, "error from rproc_pa_to_da, rproc = %p, pa = 0x%x ret = %d\n",
90 rproc, pa, ret);
91 da = 0;
92 }
93 }
94 rda = (phys_addr_t) da;
95
96 mutex_unlock(&rpc->rppcdev->lock);
97
98 return rda;
99}
100
101static void rppc_print_msg(struct rppc_instance *rpc, char *prefix,
102 char buffer[512])
103{
104 struct rppc_msg_header *hdr = (struct rppc_msg_header *)buffer;
105 struct rppc_instance_handle *hdl = NULL;
106 struct rppc_query_function *info = NULL;
107 struct rppc_packet *packet = NULL;
108 struct rppc_param_data *param = NULL;
109 struct device *dev = rpc->rppcdev->dev;
110 u32 i = 0, paramsz = sizeof(*param);
111
112 dev_dbg(dev, "%s HDR: msg_type = %d msg_len = %d\n",
113 prefix, hdr->msg_type, hdr->msg_len);
114
115 switch (hdr->msg_type) {
116 case RPPC_MSGTYPE_CREATE_RESP:
117 case RPPC_MSGTYPE_DELETE_RESP:
118 hdl = RPPC_PAYLOAD(buffer, rppc_instance_handle);
119 dev_dbg(dev, "%s endpoint = %d status = %d\n",
120 prefix, hdl->endpoint_address, hdl->status);
121 break;
122 case RPPC_MSGTYPE_FUNCTION_INFO:
123 info = RPPC_PAYLOAD(buffer, rppc_query_function);
124 dev_dbg(dev, "%s (info not yet implemented)\n", prefix);
125 break;
126 case RPPC_MSGTYPE_FUNCTION_CALL:
127 packet = RPPC_PAYLOAD(buffer, rppc_packet);
128 dev_dbg(dev, "%s PACKET: desc = %04x msg_id = %04x flags = %08x func = 0x%08x result = %d size = %u\n",
129 prefix, packet->desc, packet->msg_id,
130 packet->flags, packet->fxn_id,
131 packet->result, packet->data_size);
132 param = (struct rppc_param_data *)packet->data;
133 for (i = 0; i < (packet->data_size / paramsz); i++) {
134 dev_dbg(dev, "%s param[%u] size = %zu data = %zu (0x%08x)",
135 prefix, i, param[i].size, param[i].data,
136 param[i].data);
137 }
138 break;
139 default:
140 break;
141 }
142}
143
144/* free any outstanding function calls */
145static void rppc_delete_fxns(struct rppc_instance *rpc)
146{
147 struct rppc_function_list *pos, *n;
148
149 if (!list_empty(&rpc->fxn_list)) {
150 mutex_lock(&rpc->lock);
151 list_for_each_entry_safe(pos, n, &rpc->fxn_list, list) {
152 list_del(&pos->list);
153 kfree(pos->function);
154 kfree(pos);
155 }
156 mutex_unlock(&rpc->lock);
157 }
158}
159
160static
161struct rppc_function *rppc_find_fxn(struct rppc_instance *rpc, u16 msg_id)
162{
163 struct rppc_function *function = NULL;
164 struct rppc_function_list *pos, *n;
165 struct device *dev = rpc->rppcdev->dev;
166
167 mutex_lock(&rpc->lock);
168 list_for_each_entry_safe(pos, n, &rpc->fxn_list, list) {
169 dev_dbg(dev, "looking for msg %u, found msg %u\n",
170 msg_id, pos->msg_id);
171 if (pos->msg_id == msg_id) {
172 function = pos->function;
173 list_del(&pos->list);
174 kfree(pos);
175 break;
176 }
177 }
178 mutex_unlock(&rpc->lock);
179
180 return function;
181}
182
183static int rppc_add_fxn(struct rppc_instance *rpc,
184 struct rppc_function *function, u16 msg_id)
185{
186 struct rppc_function_list *fxn = NULL;
187 struct device *dev = rpc->rppcdev->dev;
188
189 fxn = kzalloc(sizeof(*fxn), GFP_KERNEL);
190 if (!fxn) {
191 dev_err(dev, "failed to add function %p to list with msg id %d\n",
192 function, msg_id);
193 return -ENOMEM;
194 }
195
196 fxn->function = function;
197 fxn->msg_id = msg_id;
198 mutex_lock(&rpc->lock);
199 list_add(&fxn->list, &rpc->fxn_list);
200 mutex_unlock(&rpc->lock);
201 dev_dbg(dev, "added msg id %u to list", msg_id);
202
203 return 0;
204}
205
206static
207void rppc_handle_create_resp(struct rppc_instance *rpc, char *data, int len)
208{
209 struct device *dev = rpc->rppcdev->dev;
210 struct rppc_msg_header *hdr = (struct rppc_msg_header *)data;
211 struct rppc_instance_handle *hdl;
212 u32 exp_len = sizeof(*hdl) + sizeof(*hdr);
213
214 if (len != exp_len) {
215 dev_err(dev, "invalid response message length %d (expected %d bytes)",
216 len, exp_len);
217 rpc->state = RPPC_STATE_STALE;
218 return;
219 }
220
221 hdl = RPPC_PAYLOAD(data, rppc_instance_handle);
222
223 mutex_lock(&rpc->lock);
224 if (rpc->state != RPPC_STATE_STALE && hdl->status == 0) {
225 rpc->dst = hdl->endpoint_address;
226 rpc->state = RPPC_STATE_CONNECTED;
227 } else {
228 rpc->state = RPPC_STATE_STALE;
229 }
230 rpc->in_transition = 0;
231 dev_dbg(dev, "creation response: status %d addr 0x%x\n",
232 hdl->status, hdl->endpoint_address);
233
234 complete(&rpc->reply_arrived);
235 mutex_unlock(&rpc->lock);
236}
237
238static
239void rppc_handle_delete_resp(struct rppc_instance *rpc, char *data, int len)
240{
241 struct device *dev = rpc->rppcdev->dev;
242 struct rppc_msg_header *hdr = (struct rppc_msg_header *)data;
243 struct rppc_instance_handle *hdl;
244 u32 exp_len = sizeof(*hdl) + sizeof(*hdr);
245
246 if (len != exp_len) {
247 dev_err(dev, "invalid response message length %d (expected %d bytes)",
248 len, exp_len);
249 rpc->state = RPPC_STATE_STALE;
250 return;
251 }
252 if (hdr->msg_len != sizeof(*hdl)) {
253 dev_err(dev, "disconnect message was incorrect size!\n");
254 rpc->state = RPPC_STATE_STALE;
255 return;
256 }
257
258 hdl = RPPC_PAYLOAD(data, rppc_instance_handle);
259 dev_dbg(dev, "deletion response: status %d addr 0x%x\n",
260 hdl->status, hdl->endpoint_address);
261 mutex_lock(&rpc->lock);
262 rpc->dst = 0;
263 rpc->state = RPPC_STATE_DISCONNECTED;
264 rpc->in_transition = 0;
265 complete(&rpc->reply_arrived);
266 mutex_unlock(&rpc->lock);
267}
268
269/*
270 * store the received message and wake up any blocking processes,
271 * waiting for new data. The allocated buffer would be freed after
272 * the user-space reads the packet.
273 */
274static void rppc_handle_fxn_resp(struct rppc_instance *rpc, char *data, int len)
275{
276 struct device *dev = rpc->rppcdev->dev;
277 struct rppc_msg_header *hdr = (struct rppc_msg_header *)data;
278 struct sk_buff *skb;
279 char *skbdata;
280
281 /* TODO: need to check the response length? */
282 skb = alloc_skb(hdr->msg_len, GFP_KERNEL);
283 if (!skb) {
284 dev_err(dev, "alloc_skb failed: %u\n", hdr->msg_len);
285 return;
286 }
287 skbdata = skb_put(skb, hdr->msg_len);
288 memcpy(skbdata, hdr->msg_data, hdr->msg_len);
289
290 mutex_lock(&rpc->lock);
291 skb_queue_tail(&rpc->queue, skb);
292 mutex_unlock(&rpc->lock);
293
294 wake_up_interruptible(&rpc->readq);
295}
296
297/*
298 * callback function for processing the different responses
299 * from the remote processor on a particular rpmsg channel
300 * instance.
301 */
302static void rppc_cb(struct rpmsg_channel *rpdev,
303 void *data, int len, void *priv, u32 src)
304{
305 struct rppc_msg_header *hdr = data;
306 struct rppc_instance *rpc = priv;
307 struct device *dev = rpc->rppcdev->dev;
308 char *buf = (char *)data;
309
310 dev_dbg(dev, "<== incoming msg src %d len %d msg_type %d msg_len %d\n",
311 src, len, hdr->msg_type, hdr->msg_len);
312 rppc_print_msg(rpc, "RX:", buf);
313
314 if (len <= sizeof(*hdr)) {
315 dev_err(dev, "message truncated\n");
316 rpc->state = RPPC_STATE_STALE;
317 return;
318 }
319
320 switch (hdr->msg_type) {
321 case RPPC_MSGTYPE_CREATE_RESP:
322 rppc_handle_create_resp(rpc, data, len);
323 break;
324 case RPPC_MSGTYPE_DELETE_RESP:
325 rppc_handle_delete_resp(rpc, data, len);
326 break;
327 case RPPC_MSGTYPE_FUNCTION_CALL:
328 case RPPC_MSGTYPE_FUNCTION_RET:
329 rppc_handle_fxn_resp(rpc, data, len);
330 break;
331 default:
332 dev_warn(dev, "unexpected msg type: %d\n", hdr->msg_type);
333 break;
334 }
335}
336
337/*
338 * send a connection request to the remote rpc connection service. Use
339 * the new local address created during .open for this instance as the
340 * source address to complete the connection.
341 */
342static int rppc_connect(struct rppc_instance *rpc,
343 struct rppc_create_instance *connect)
344{
345 int ret = 0;
346 u32 len = 0;
347 char kbuf[512];
348 struct rppc_device *rppcdev = rpc->rppcdev;
349 struct rppc_msg_header *hdr = (struct rppc_msg_header *)&kbuf[0];
350
351 if (rpc->state == RPPC_STATE_CONNECTED) {
352 dev_dbg(rppcdev->dev, "endpoint already connected\n");
353 return -EISCONN;
354 }
355
356 hdr->msg_type = RPPC_MSGTYPE_CREATE_REQ;
357 hdr->msg_len = sizeof(*connect);
358 memcpy(hdr->msg_data, connect, hdr->msg_len);
359 len = sizeof(struct rppc_msg_header) + hdr->msg_len;
360
361 init_completion(&rpc->reply_arrived);
362 rpc->in_transition = 1;
363 ret = rpmsg_send_offchannel(rppcdev->rpdev, rpc->ept->addr,
364 rppcdev->rpdev->dst, (char *)kbuf, len);
365 if (ret > 0) {
366 dev_err(rppcdev->dev, "rpmsg_send failed: %d\n", ret);
367 return ret;
368 }
369
370 ret = wait_for_completion_interruptible_timeout(&rpc->reply_arrived,
371 msecs_to_jiffies(5000));
372 if (rpc->state == RPPC_STATE_CONNECTED)
373 return 0;
374
375 if (rpc->state == RPPC_STATE_STALE)
376 return -ENXIO;
377
378 if (ret > 0) {
379 dev_err(rppcdev->dev, "premature wakeup: %d\n", ret);
380 return -EIO;
381 }
382
383 return -ETIMEDOUT;
384}
385
386static void rppc_disconnect(struct rppc_instance *rpc)
387{
388 int ret;
389 size_t len;
390 char kbuf[512];
391 struct rppc_device *rppcdev = rpc->rppcdev;
392 struct rppc_msg_header *hdr = (struct rppc_msg_header *)&kbuf[0];
393 struct rppc_instance_handle *handle =
394 RPPC_PAYLOAD(kbuf, rppc_instance_handle);
395
396 if (rpc->state != RPPC_STATE_CONNECTED)
397 return;
398
399 hdr->msg_type = RPPC_MSGTYPE_DELETE_REQ;
400 hdr->msg_len = sizeof(uint32_t);
401 handle->endpoint_address = rpc->dst;
402 handle->status = 0;
403 len = sizeof(struct rppc_msg_header) + hdr->msg_len;
404
405 dev_dbg(rppcdev->dev, "disconnecting from RPC service at %d\n",
406 rpc->dst);
407 ret = rpmsg_send_offchannel(rppcdev->rpdev, rpc->ept->addr,
408 rppcdev->rpdev->dst, kbuf, len);
409 if (ret)
410 dev_err(rppcdev->dev, "rpmsg_send failed: %d\n", ret);
411
412 /*
413 * TODO: should we wait for a message to come back?
414 * For now, no.
415 */
416 wait_for_completion_interruptible(&rpc->reply_arrived);
417}
418
419static int rppc_register_buffers(struct rppc_instance *rpc,
420 unsigned long arg)
421{
422 struct rppc_buf_fds data;
423 int *fds = NULL;
424 struct rppc_dma_buf **bufs = NULL;
425 struct rppc_dma_buf *tmp;
426 int i = 0, ret = 0;
427
428 if (copy_from_user(&data, (char __user *)arg, sizeof(data)))
429 return -EFAULT;
430
431 /* impose a maximum number of buffers for now */
432 if (data.num > RPPC_MAX_REG_FDS)
433 return -EINVAL;
434
435 fds = kzalloc(sizeof(*fds) * data.num, GFP_KERNEL);
436 if (!fds)
437 return -ENOMEM;
438
439 if (copy_from_user(fds, (char __user *)data.fds,
440 sizeof(*fds) * data.num)) {
441 ret = -EFAULT;
442 goto free_fds;
443 }
444
445 for (i = 0; i < data.num; i++) {
446 if (!fcheck(fds[i])) {
447 ret = -EBADF;
448 goto free_fds;
449 }
450
451 tmp = rppc_find_dmabuf(rpc, fds[i]);
452 if (!IS_ERR_OR_NULL(tmp)) {
453 ret = -EEXIST;
454 goto free_fds;
455 }
456 }
457
458 bufs = kzalloc(sizeof(*bufs) * data.num, GFP_KERNEL);
459 if (!bufs) {
460 ret = -ENOMEM;
461 goto free_fds;
462 }
463
464 for (i = 0; i < data.num; i++) {
465 bufs[i] = rppc_alloc_dmabuf(rpc, fds[i], false);
466 if (IS_ERR(bufs[i])) {
467 ret = PTR_ERR(bufs[i]);
468 break;
469 }
470 }
471 if (i == data.num)
472 goto free_bufs;
473
474 for (i -= 1; i >= 0; i--)
475 rppc_free_dmabuf(bufs[i]->id, bufs[i], rpc);
476
477free_bufs:
478 kfree(bufs);
479free_fds:
480 kfree(fds);
481 return ret;
482}
483
484static int rppc_unregister_buffers(struct rppc_instance *rpc,
485 unsigned long arg)
486{
487 struct rppc_buf_fds data;
488 int *fds = NULL;
489 struct rppc_dma_buf **bufs = NULL;
490 int i = 0, ret = 0;
491
492 if (copy_from_user(&data, (char __user *)arg, sizeof(data)))
493 return -EFAULT;
494
495 /* impose a maximum number of buffers for now */
496 if (data.num > RPPC_MAX_REG_FDS)
497 return -EINVAL;
498
499 fds = kzalloc(sizeof(*fds) * data.num, GFP_KERNEL);
500 if (!fds)
501 return -ENOMEM;
502
503 if (copy_from_user(fds, (char __user *)data.fds,
504 sizeof(*fds) * data.num)) {
505 ret = -EFAULT;
506 goto free_fds;
507 }
508
509 bufs = kzalloc(sizeof(*bufs) * data.num, GFP_KERNEL);
510 if (!bufs) {
511 ret = -ENOMEM;
512 goto free_fds;
513 }
514
515 for (i = 0; i < data.num; i++) {
516 if (!fcheck(fds[i])) {
517 ret = -EBADF;
518 goto free_bufs;
519 }
520
521 bufs[i] = rppc_find_dmabuf(rpc, fds[i]);
522 if (IS_ERR_OR_NULL(bufs[i])) {
523 ret = -EEXIST;
524 goto free_bufs;
525 }
526 }
527
528 for (i = 0; i < data.num; i++)
529 rppc_free_dmabuf(bufs[i]->id, bufs[i], rpc);
530
531free_bufs:
532 kfree(bufs);
533free_fds:
534 kfree(fds);
535 return ret;
536}
537
538/*
539 * create a new rpc instance that a user-space client can use to invoke
540 * remote functions. A new local address would be created and tied with
541 * this instance for uniquely identifying the messages communicated by
542 * this instance with the remote side.
543 *
544 * The function is blocking if there is no underlying connection manager
545 * channel, unless the device is opened with non-blocking flags specifically.
546 */
547static int rppc_open(struct inode *inode, struct file *filp)
548{
549 struct rppc_device *rppcdev;
550 struct rppc_instance *rpc;
551
552 rppcdev = container_of(inode->i_cdev, struct rppc_device, cdev);
553
554 if (!rppcdev->rpdev)
555 if ((filp->f_flags & O_NONBLOCK) ||
556 wait_for_completion_interruptible(&rppcdev->comp))
557 return -EBUSY;
558
559 rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
560 if (!rpc)
561 return -ENOMEM;
562
563 mutex_init(&rpc->lock);
564 skb_queue_head_init(&rpc->queue);
565 init_waitqueue_head(&rpc->readq);
566 INIT_LIST_HEAD(&rpc->fxn_list);
567 idr_init(&rpc->dma_idr);
568 rpc->in_transition = 0;
569 rpc->msg_id = 0;
570 rpc->state = RPPC_STATE_DISCONNECTED;
571 rpc->rppcdev = rppcdev;
572
573 rpc->ept = rpmsg_create_ept(rppcdev->rpdev, rppc_cb, rpc,
574 RPMSG_ADDR_ANY);
575 if (!rpc->ept) {
576 dev_err(rppcdev->dev, "create ept failed\n");
577 kfree(rpc);
578 return -ENOMEM;
579 }
580 filp->private_data = rpc;
581
582 mutex_lock(&rppcdev->lock);
583 list_add(&rpc->list, &rppcdev->instances);
584 mutex_unlock(&rppcdev->lock);
585
586 dev_dbg(rppcdev->dev, "local addr assigned: 0x%x\n", rpc->ept->addr);
587
588 return 0;
589}
590
591/*
592 * release and free all the resources associated with a particular rpc
593 * instance. This includes the data structures maintaining the current
594 * outstanding function invocations, and all the buffers registered for
595 * use with this instance. Send a disconnect message and cleanup the
596 * local end-point only if the instance is in a normal state, with the
597 * remote connection manager functional.
598 */
599static int rppc_release(struct inode *inode, struct file *filp)
600{
601 struct rppc_instance *rpc = filp->private_data;
602 struct rppc_device *rppcdev = rpc->rppcdev;
603
604 dev_dbg(rppcdev->dev, "releasing Instance %p, in state %d\n", rpc,
605 rpc->state);
606
607 if (rpc->state != RPPC_STATE_STALE) {
608 if (rpc->ept) {
609 rppc_disconnect(rpc);
610 rpmsg_destroy_ept(rpc->ept);
611 rpc->ept = NULL;
612 }
613 }
614
615 rppc_delete_fxns(rpc);
616
617 mutex_lock(&rpc->lock);
618 idr_for_each(&rpc->dma_idr, rppc_free_dmabuf, rpc);
619 idr_destroy(&rpc->dma_idr);
620 mutex_unlock(&rpc->lock);
621
622 mutex_lock(&rppcdev->lock);
623 list_del(&rpc->list);
624 mutex_unlock(&rppcdev->lock);
625
626 dev_dbg(rppcdev->dev, "instance %p has been deleted!\n", rpc);
627 if (list_empty(&rppcdev->instances))
628 dev_dbg(rppcdev->dev, "all instances have been removed!\n");
629
630 kfree(rpc);
631 return 0;
632}
633
634static long rppc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
635{
636 struct rppc_instance *rpc = filp->private_data;
637 struct rppc_device *rppcdev = rpc->rppcdev;
638 struct rppc_create_instance connect;
639 int ret = 0;
640
641 dev_dbg(rppcdev->dev, "%s: cmd %d, arg 0x%lx\n", __func__, cmd, arg);
642
643 if (_IOC_TYPE(cmd) != RPPC_IOC_MAGIC)
644 return -ENOTTY;
645
646 if (_IOC_NR(cmd) > RPPC_IOC_MAXNR)
647 return -ENOTTY;
648
649 switch (cmd) {
650 case RPPC_IOC_CREATE:
651 ret = copy_from_user(&connect, (char __user *)arg,
652 sizeof(connect));
653 if (ret) {
654 dev_err(rppcdev->dev, "%s: %d: copy_from_user fail: %d\n",
655 __func__, _IOC_NR(cmd), ret);
656 ret = -EFAULT;
657 } else {
658 connect.name[sizeof(connect.name) - 1] = '\0';
659 ret = rppc_connect(rpc, &connect);
660 }
661 break;
662 case RPPC_IOC_BUFREGISTER:
663 ret = rppc_register_buffers(rpc, arg);
664 break;
665 case RPPC_IOC_BUFUNREGISTER:
666 ret = rppc_unregister_buffers(rpc, arg);
667 break;
668 default:
669 dev_err(rppcdev->dev, "unhandled ioctl cmd: %d\n", cmd);
670 break;
671 }
672
673 return ret;
674}
675
676static ssize_t rppc_read(struct file *filp, char __user *buf, size_t len,
677 loff_t *offp)
678{
679 struct rppc_instance *rpc = filp->private_data;
680 struct rppc_packet *packet = NULL;
681 struct rppc_param_data *parameters = NULL;
682 struct rppc_function *function = NULL;
683 struct rppc_function_return returned;
684 struct sk_buff *skb = NULL;
685 int ret = 0;
686 int use = sizeof(returned);
687 DEFINE_WAIT(wait);
688
689 if (mutex_lock_interruptible(&rpc->lock))
690 return -ERESTARTSYS;
691
692 /* instance is invalid */
693 if (rpc->state == RPPC_STATE_STALE) {
694 mutex_unlock(&rpc->lock);
695 return -ENXIO;
696 }
697
698 /* not yet connected to the remote side */
699 if (rpc->state == RPPC_STATE_DISCONNECTED) {
700 mutex_unlock(&rpc->lock);
701 return -ENOTCONN;
702 }
703
704 if (len > use) {
705 mutex_unlock(&rpc->lock);
706 return -EOVERFLOW;
707 }
708 if (len < use) {
709 mutex_unlock(&rpc->lock);
710 return -EINVAL;
711 }
712
713 while (skb_queue_empty(&rpc->queue)) {
714 mutex_unlock(&rpc->lock);
715 /* non-blocking requested ? return now */
716 if (filp->f_flags & O_NONBLOCK)
717 return -EAGAIN;
718
719 prepare_to_wait_exclusive(&rpc->readq, &wait,
720 TASK_INTERRUPTIBLE);
721 schedule();
722 finish_wait(&rpc->readq, &wait);
723 if (signal_pending(current))
724 return -ERESTARTSYS;
725
726 ret = mutex_lock_interruptible(&rpc->lock);
727 if (ret < 0)
728 return -ERESTARTSYS;
729
730 /* make sure state is sane while we waited */
731 if (rpc->state != RPPC_STATE_CONNECTED) {
732 ret = -EIO;
733 goto out;
734 }
735 }
736
737 skb = skb_dequeue(&rpc->queue);
738 if (WARN_ON(!skb)) {
739 ret = -EIO;
740 goto out;
741 }
742 mutex_unlock(&rpc->lock);
743
744 packet = (struct rppc_packet *)skb->data;
745 parameters = (struct rppc_param_data *)packet->data;
746
747 /*
748 * pull the function memory from the list and untranslate
749 * the remote device address pointers in the packet back
750 * to MPU pointers.
751 */
752 function = rppc_find_fxn(rpc, packet->msg_id);
753 if (function && function->num_translations > 0) {
754 ret = rppc_xlate_buffers(rpc, function, RPPC_RPA_TO_UVA);
755 if (ret < 0)
756 goto failure;
757 }
758 returned.fxn_id = RPPC_FXN_MASK(packet->fxn_id);
759 returned.status = packet->result;
760
761 if (copy_to_user(buf, &returned, use)) {
762 dev_err(rpc->rppcdev->dev, "%s: copy_to_user fail\n", __func__);
763 ret = -EFAULT;
764 } else {
765 ret = use;
766 }
767
768failure:
769 kfree(function);
770 kfree_skb(skb);
771out:
772 return ret;
773}
774
775static ssize_t rppc_write(struct file *filp, const char __user *ubuf,
776 size_t len, loff_t *offp)
777{
778 struct rppc_instance *rpc = filp->private_data;
779 struct rppc_device *rppcdev = rpc->rppcdev;
780 struct device *dev = rppcdev->dev;
781 struct rppc_msg_header *hdr = NULL;
782 struct rppc_function *function = NULL;
783 struct rppc_packet *packet = NULL;
784 struct rppc_param_data *parameters = NULL;
785 char kbuf[512];
786 int use = 0, ret = 0, param = 0;
787 uint32_t sig_idx = 0;
788 uint32_t sig_prm = 0;
789 static u32 rppc_atomic_size[RPPC_PARAM_ATOMIC_MAX] = {
790 0, /* RPPC_PARAM_VOID */
791 1, /* RPPC_PARAM_S08 */
792 1, /* RPPC_PARAM_U08 */
793 2, /* RPPC_PARAM_S16 */
794 2, /* RPPC_PARAM_U16 */
795 4, /* RPPC_PARAM_S32 */
796 4, /* RPPC_PARAM_U32 */
797 8, /* RPPC_PARAM_S64 */
798 8 /* RPPC_PARAM_U64 */
799 };
800
801 if (len < sizeof(*function)) {
802 ret = -ENOTSUPP;
803 goto failure;
804 }
805
806 if (len > (sizeof(*function) + RPPC_MAX_TRANSLATIONS *
807 sizeof(struct rppc_param_translation))) {
808 ret = -ENOTSUPP;
809 goto failure;
810 }
811
812 if (rpc->state != RPPC_STATE_CONNECTED) {
813 ret = -ENOTCONN;
814 goto failure;
815 }
816
817 function = kzalloc(len, GFP_KERNEL);
818 if (function == NULL) {
819 ret = -ENOMEM;
820 goto failure;
821 }
822
823 if (copy_from_user(function, ubuf, len)) {
824 ret = -EMSGSIZE;
825 goto failure;
826 }
827
828 /* increment the message id and wrap if needed */
829 rpc->msg_id = (rpc->msg_id + 1) & 0xFFFF;
830
831 memset(kbuf, 0, sizeof(kbuf));
832 sig_idx = function->fxn_id + 1;
833 hdr = (struct rppc_msg_header *)kbuf;
834 hdr->msg_type = RPPC_MSGTYPE_FUNCTION_CALL;
835 hdr->msg_len = sizeof(*packet);
836 packet = RPPC_PAYLOAD(kbuf, rppc_packet);
837 packet->desc = RPPC_DESC_EXEC_SYNC;
838 packet->msg_id = rpc->msg_id;
839 packet->flags = (RPPC_JOBID_DISCRETE << 16) | RPPC_POOLID_DEFAULT;
840 packet->fxn_id = RPPC_SET_FXN_IDX(function->fxn_id);
841 packet->result = 0;
842 packet->data_size = sizeof(*parameters) * function->num_params;
843
844 /* check the signatures against what were published */
845 if (RPPC_SIG_NUM_PARAM(rppcdev->signatures[sig_idx]) !=
846 function->num_params) {
847 dev_err(dev, "number of parameters mismatch! params = %u expected = %u\n",
848 function->num_params,
849 RPPC_SIG_NUM_PARAM(rppcdev->signatures[sig_idx]));
850 ret = -EINVAL;
851 goto failure;
852 }
853
854 /*
855 * compute the parameter pointer changes last since this will cause the
856 * cache operations
857 */
858 parameters = (struct rppc_param_data *)packet->data;
859 for (param = 0; param < function->num_params; param++) {
860 sig_prm = param + 1;
861 /*
862 * check to make sure the parameter description matches the
863 * signature published from the other side.
864 */
865 if (function->params[param].type == RPPC_PARAM_TYPE_PTR &&
866 !RPPC_IS_PTR(
867 rppcdev->signatures[sig_idx].params[sig_prm].type)) {
868 dev_err(dev, "parameter %u Pointer Type Mismatch sig type:%x func %u\n",
869 param, rppcdev->signatures[sig_idx].
870 params[sig_prm].type, sig_idx);
871 ret = -EINVAL;
872 goto failure;
873 } else if (param > 0 && function->params[param].type ==
874 RPPC_PARAM_TYPE_ATOMIC) {
875 if (!RPPC_IS_ATOMIC(
876 rppcdev->signatures[sig_idx].params[sig_prm].type)) {
877 dev_err(dev, "parameter Atomic Type Mismatch\n");
878 ret = -EINVAL;
879 goto failure;
880 } else {
881 uint32_t t = rppcdev->signatures[sig_idx].
882 params[sig_prm].type;
883 if (rppc_atomic_size[t] !=
884 function->params[param].size) {
885 dev_err(dev, "size mismatch! u:%u sig:%u\n",
886 function->params[param].size,
887 rppc_atomic_size[t]);
888 ret = -EINVAL;
889 goto failure;
890 }
891 }
892 }
893
894 parameters[param].size = function->params[param].size;
895
896 /* check the type and lookup if it's a pointer */
897 if (function->params[param].type == RPPC_PARAM_TYPE_PTR) {
898 /*
899 * internally the buffer translations takes care of the
900 * offsets.
901 */
902 int fd = function->params[param].fd;
903 parameters[param].data = (size_t) rppc_buffer_lookup(
904 rpc,
905 (virt_addr_t)
906 function->
907 params[param].data,
908 (virt_addr_t)
909 function->
910 params[param].base,
911 fd);
912 } else if (function->params[param].type ==
913 RPPC_PARAM_TYPE_ATOMIC) {
914 parameters[param].data = function->params[param].data;
915 } else {
916 ret = -ENOTSUPP;
917 goto failure;
918 }
919 }
920
921 /* compute the size of the rpmsg packet */
922 use = sizeof(*hdr) + hdr->msg_len + packet->data_size;
923
924 /* failed to provide the translation data */
925 if (function->num_translations > 0 &&
926 len < (sizeof(*function) + (function->num_translations *
927 sizeof(struct rppc_param_translation)))) {
928 ret = -ENXIO;
929 goto failure;
930 }
931
932 /*
933 * if there are pointers to translate for the user, do so now.
934 * alter our copy of function and the user's parameters so that
935 * the proper pointers can be sent to remote cores
936 */
937 if (function->num_translations > 0) {
938 ret = rppc_xlate_buffers(rpc, function, RPPC_UVA_TO_RPA);
939 if (ret < 0) {
940 dev_err(dev, "failed to translate all pointers for remote core!\n");
941 goto failure;
942 }
943 }
944
945 ret = rppc_add_fxn(rpc, function, rpc->msg_id);
946 if (ret < 0) {
947 rppc_xlate_buffers(rpc, function, RPPC_RPA_TO_UVA);
948 goto failure;
949 }
950
951 rppc_print_msg(rpc, "TX:", kbuf);
952
953 ret = rpmsg_send_offchannel(rppcdev->rpdev, rpc->ept->addr, rpc->dst,
954 kbuf, use);
955 if (ret) {
956 dev_err(dev, "rpmsg_send failed: %d\n", ret);
957 rppc_find_fxn(rpc, rpc->msg_id);
958 rppc_xlate_buffers(rpc, function, RPPC_RPA_TO_UVA);
959 goto failure;
960 }
961 dev_dbg(dev, "==> sent msg to remote endpoint %u\n", rpc->dst);
962
963failure:
964 if (ret >= 0)
965 ret = len;
966 else
967 kfree(function);
968
969 return ret;
970}
971
972static unsigned int rppc_poll(struct file *filp, struct poll_table_struct *wait)
973{
974 struct rppc_instance *rpc = filp->private_data;
975 unsigned int mask = 0;
976
977 if (mutex_lock_interruptible(&rpc->lock))
978 return -ERESTARTSYS;
979
980 poll_wait(filp, &rpc->readq, wait);
981 if (rpc->state == RPPC_STATE_STALE) {
982 mask = POLLERR;
983 goto out;
984 }
985
986 /* if the queue is not empty set the poll bit correctly */
987 if (!skb_queue_empty(&rpc->queue))
988 mask |= (POLLIN | POLLRDNORM);
989
990 /* TODO: writes are deemed to be successful always, fix this later */
991 if (true)
992 mask |= POLLOUT | POLLWRNORM;
993
994out:
995 mutex_unlock(&rpc->lock);
996 return mask;
997}
998
999static const struct file_operations rppc_fops = {
1000 .owner = THIS_MODULE,
1001 .open = rppc_open,
1002 .release = rppc_release,
1003 .unlocked_ioctl = rppc_ioctl,
1004 .read = rppc_read,
1005 .write = rppc_write,
1006 .poll = rppc_poll,
1007};
1008
1009/*
1010 * send a function query message, the sysfs entry will be created
1011 * during the processing of the response message
1012 */
1013static int rppc_query_function(struct rpmsg_channel *rpdev)
1014{
1015 int ret = 0;
1016 u32 len = 0;
1017 char kbuf[512];
1018 struct rppc_device *rppcdev = dev_get_drvdata(&rpdev->dev);
1019 struct rppc_msg_header *hdr = (struct rppc_msg_header *)&kbuf[0];
1020 struct rppc_query_function *fxn_info =
1021 (struct rppc_query_function *)hdr->msg_data;
1022
1023 if (rppcdev->cur_func >= rppcdev->num_funcs)
1024 return -EINVAL;
1025
1026 hdr->msg_type = RPPC_MSGTYPE_FUNCTION_QUERY;
1027 hdr->msg_len = sizeof(*fxn_info);
1028 len = sizeof(*hdr) + hdr->msg_len;
1029 fxn_info->info_type = RPPC_INFOTYPE_FUNC_SIGNATURE;
1030 fxn_info->fxn_id = rppcdev->cur_func++;
1031
1032 dev_dbg(&rpdev->dev, "sending function query type %u for function %u\n",
1033 fxn_info->info_type, fxn_info->fxn_id);
1034 ret = rpmsg_send(rpdev, (char *)kbuf, len);
1035 if (ret) {
1036 dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
1037 return ret;
1038 }
1039
1040 return 0;
1041}
1042
1043static void
1044rppc_handle_devinfo_resp(struct rpmsg_channel *rpdev, char *data, int len)
1045{
1046 struct rppc_device *rppcdev = dev_get_drvdata(&rpdev->dev);
1047 struct rppc_device_info *info;
1048 u32 exp_len = sizeof(*info) + sizeof(struct rppc_msg_header);
1049
1050 if (len != exp_len) {
1051 dev_err(&rpdev->dev, "invalid message length %d (expected %d bytes)",
1052 len, exp_len);
1053 return;
1054 }
1055
1056 info = RPPC_PAYLOAD(data, rppc_device_info);
1057 if (info->num_funcs > RPPC_MAX_NUM_FUNCS) {
1058 rppcdev->num_funcs = 0;
1059 dev_err(&rpdev->dev, "number of functions (%d) exceeds the limit supported(%d)\n",
1060 info->num_funcs, RPPC_MAX_NUM_FUNCS);
1061 return;
1062 }
1063
1064 rppcdev->num_funcs = info->num_funcs;
1065 rppcdev->signatures = kzalloc(rppcdev->num_funcs *
1066 sizeof(struct rppc_func_signature), GFP_KERNEL);
1067 if (!rppcdev->signatures) {
1068 dev_err(&rpdev->dev, "failed to alloc signatures\n");
1069 return;
1070 }
1071
1072 dev_info(&rpdev->dev, "publised functions = %u\n", info->num_funcs);
1073
1074 /* send the function query for first function */
1075 if (rppc_query_function(rpdev) == -EINVAL)
1076 dev_err(&rpdev->dev, "failed to get a reasonable number of functions!\n");
1077}
1078
1079static void
1080rppc_handle_fxninfo_resp(struct rpmsg_channel *rpdev, char *data, int len)
1081{
1082 struct rppc_device *rppcdev = dev_get_drvdata(&rpdev->dev);
1083 struct rppc_query_function *fxn_info;
1084 struct rppc_func_signature *signature;
1085 u32 exp_len = sizeof(*fxn_info) + sizeof(struct rppc_msg_header);
1086 int i;
1087
1088 if (len != exp_len) {
1089 dev_err(&rpdev->dev, "invalid message length %d (expected %d bytes)",
1090 len, exp_len);
1091 return;
1092 }
1093
1094 fxn_info = RPPC_PAYLOAD(data, rppc_query_function);
1095 dev_dbg(&rpdev->dev, "response for function query of type %u\n",
1096 fxn_info->info_type);
1097
1098 switch (fxn_info->info_type) {
1099 case RPPC_INFOTYPE_FUNC_SIGNATURE:
1100 if (fxn_info->fxn_id >= rppcdev->num_funcs) {
1101 dev_err(&rpdev->dev, "function(%d) is out of range!\n",
1102 fxn_info->fxn_id);
1103 break;
1104 }
1105
1106 memcpy(&rppcdev->signatures[fxn_info->fxn_id],
1107 &fxn_info->info.signature, sizeof(*signature));
1108
1109 /* TODO: delete these debug prints later */
1110 dev_dbg(&rpdev->dev, "received info for func(%d); name = %s #params = %u\n",
1111 fxn_info->fxn_id, fxn_info->info.signature.name,
1112 fxn_info->info.signature.num_param);
1113 signature = &rppcdev->signatures[fxn_info->fxn_id];
1114 for (i = 0; i < signature->num_param; i++) {
1115 dev_dbg(&rpdev->dev, "param[%u] type = %x dir = %u\n",
1116 i, signature->params[i].type,
1117 signature->params[i].direction);
1118 }
1119
1120 /* query again until we've hit our limit */
1121 if (rppc_query_function(rpdev) == -EINVAL) {
1122 dev_dbg(&rpdev->dev, "reached end of function list!\n");
1123 rppc_create_sysfs(rppcdev);
1124 }
1125 break;
1126 default:
1127 dev_err(&rpdev->dev, "unrecognized fxn query response %u\n",
1128 fxn_info->info_type);
1129 break;
1130 }
1131}
1132
1133static void rppc_driver_cb(struct rpmsg_channel *rpdev, void *data, int len,
1134 void *priv, u32 src)
1135{
1136 struct rppc_msg_header *hdr = data;
1137 char *buf = (char *)data;
1138
1139 dev_dbg(&rpdev->dev, "<== incoming drv msg src %d len %d msg_type %d msg_len %d\n",
1140 src, len, hdr->msg_type, hdr->msg_len);
1141
1142 if (len <= sizeof(*hdr)) {
1143 dev_err(&rpdev->dev, "message truncated\n");
1144 return;
1145 }
1146
1147 switch (hdr->msg_type) {
1148 case RPPC_MSGTYPE_DEVINFO_RESP:
1149 rppc_handle_devinfo_resp(rpdev, buf, len);
1150 break;
1151 case RPPC_MSGTYPE_FUNCTION_INFO:
1152 rppc_handle_fxninfo_resp(rpdev, buf, len);
1153 break;
1154 default:
1155 dev_err(&rpdev->dev, "unrecognized message type %u\n",
1156 hdr->msg_type);
1157 break;
1158 }
1159}
1160
1161static int find_rpccdev_by_name(int id, void *p, void *data)
1162{
1163 struct rppc_device *rppcdev = p;
1164
1165 return strcmp(dev_name(rppcdev->dev), data) ? 0 : (int)p;
1166}
1167
1168/*
1169 * send a device info query message, the device will be created
1170 * during the processing of the response message
1171 */
1172static int rppc_device_create(struct rpmsg_channel *rpdev)
1173{
1174 int ret;
1175 u32 len;
1176 char kbuf[512];
1177 struct rppc_msg_header *hdr = (struct rppc_msg_header *)&kbuf[0];
1178
1179 hdr->msg_type = RPPC_MSGTYPE_DEVINFO_REQ;
1180 hdr->msg_len = 0;
1181 len = sizeof(*hdr);
1182 ret = rpmsg_send(rpdev, (char *)kbuf, len);
1183 if (ret) {
1184 dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
1185 return ret;
1186 }
1187
1188 return 0;
1189}
1190
1191static int rppc_probe(struct rpmsg_channel *rpdev)
1192{
1193 int ret, major, minor;
1194 struct rppc_device *rppcdev = NULL;
1195 dev_t dev;
1196 char namedesc[RPMSG_NAME_SIZE];
1197
1198 dev_info(&rpdev->dev, "probing service %s with src %u dst %u\n",
1199 rpdev->desc, rpdev->src, rpdev->dst);
1200
1201 mutex_lock(&rppc_devices_lock);
1202 snprintf(namedesc, sizeof(namedesc), "%s", rpdev->desc);
1203 rppcdev = (struct rppc_device *)idr_for_each(&rppc_devices,
1204 find_rpccdev_by_name, namedesc);
1205 if (rppcdev) {
1206 rppcdev->rpdev = rpdev;
1207 dev_set_drvdata(&rpdev->dev, rppcdev);
1208 goto serv_up;
1209 }
1210
1211 rppcdev = kzalloc(sizeof(*rppcdev), GFP_KERNEL);
1212 if (!rppcdev) {
1213 ret = -ENOMEM;
1214 goto exit;
1215 }
1216
1217 minor = idr_alloc(&rppc_devices, rppcdev, 0, 0, GFP_KERNEL);
1218 if (minor < 0) {
1219 ret = minor;
1220 dev_err(&rpdev->dev, "failed to get a minor number: %d\n", ret);
1221 goto free_rppcdev;
1222 }
1223
1224 INIT_LIST_HEAD(&rppcdev->instances);
1225 mutex_init(&rppcdev->lock);
1226 init_completion(&rppcdev->comp);
1227
1228 rppcdev->minor = minor;
1229 rppcdev->rpdev = rpdev;
1230 dev_set_drvdata(&rpdev->dev, rppcdev);
1231
1232 major = MAJOR(rppc_dev);
1233 cdev_init(&rppcdev->cdev, &rppc_fops);
1234 rppcdev->cdev.owner = THIS_MODULE;
1235 dev = MKDEV(major, minor);
1236 ret = cdev_add(&rppcdev->cdev, dev, 1);
1237 if (ret) {
1238 dev_err(&rpdev->dev, "cdev_add failed: %d\n", ret);
1239 goto free_id;
1240 }
1241
1242 rppcdev->dev = device_create(rppc_class, &rpdev->dev, dev, NULL,
1243 namedesc);
1244 if (IS_ERR(rppcdev->dev)) {
1245 int ret = PTR_ERR(rppcdev->dev);
1246 dev_err(&rpdev->dev, "device_create failed: %d\n", ret);
1247 goto free_cdev;
1248 }
1249 dev_set_drvdata(rppcdev->dev, rppcdev);
1250
1251serv_up:
1252 ret = rppc_device_create(rpdev);
1253 if (ret) {
1254 dev_err(&rpdev->dev, "failed to query channel info: %d\n", ret);
1255 dev = MKDEV(MAJOR(rppc_dev), rppcdev->minor);
1256 goto free_dev;
1257 }
1258
1259 complete_all(&rppcdev->comp);
1260
1261 dev_dbg(&rpdev->dev, "new RPPC connection srv channel: %u -> %u!\n",
1262 rpdev->src, rpdev->dst);
1263
1264 mutex_unlock(&rppc_devices_lock);
1265 return 0;
1266
1267free_dev:
1268 device_destroy(rppc_class, dev);
1269free_cdev:
1270 cdev_del(&rppcdev->cdev);
1271free_id:
1272 idr_remove(&rppc_devices, rppcdev->minor);
1273free_rppcdev:
1274 kfree(rppcdev);
1275exit:
1276 mutex_unlock(&rppc_devices_lock);
1277 return ret;
1278}
1279
1280static void rppc_remove(struct rpmsg_channel *rpdev)
1281{
1282 struct rppc_device *rppcdev = dev_get_drvdata(&rpdev->dev);
1283 struct rppc_instance *rpc = NULL;
1284 int major = MAJOR(rppc_dev);
1285
1286 dev_dbg(rppcdev->dev, "removing rpmsg-rpc device %u.%u\n",
1287 major, rppcdev->minor);
1288
1289 mutex_lock(&rppc_devices_lock);
1290
1291 rppc_remove_sysfs(rppcdev);
1292 rppcdev->cur_func = 0;
1293 kfree(rppcdev->signatures);
1294
1295 /* if there are no instances in the list, just teardown */
1296 if (list_empty(&rppcdev->instances)) {
1297 dev_dbg(&rpdev->dev, "no instances, removing device!\n");
1298 device_destroy(rppc_class, MKDEV(major, rppcdev->minor));
1299 cdev_del(&rppcdev->cdev);
1300 idr_remove(&rppc_devices, rppcdev->minor);
1301 kfree(rppcdev);
1302 mutex_unlock(&rppc_devices_lock);
1303 return;
1304 }
1305
1306 /*
1307 * if there are rpc instances that means that this is a recovery
1308 * operation. Don't clean the rppcdev, and retain it for reuse.
1309 * mark each instance as invalid, and complete any on-going transactions
1310 */
1311 init_completion(&rppcdev->comp);
1312 mutex_lock(&rppcdev->lock);
1313 list_for_each_entry(rpc, &rppcdev->instances, list) {
1314 dev_dbg(rppcdev->dev, "instance %p in state %d\n",
1315 rpc, rpc->state);
1316 if ((rpc->state == RPPC_STATE_CONNECTED) && rpc->in_transition)
1317 complete_all(&rpc->reply_arrived);
1318 rpc->state = RPPC_STATE_STALE;
1319 wake_up_interruptible(&rpc->readq);
1320 }
1321 rppcdev->rpdev = NULL;
1322 mutex_unlock(&rppcdev->lock);
1323 mutex_unlock(&rppc_devices_lock);
1324 dev_dbg(&rpdev->dev, "removed rpmsg rpmsgrpc driver.\n");
1325}
1326
1327static struct rpmsg_device_id rppc_id_table[] = {
1328 {.name = "rpmsg-rpc"},
1329 {},
1330};
1331
1332static struct rpmsg_driver rppc_driver = {
1333 .drv.name = KBUILD_MODNAME,
1334 .drv.owner = THIS_MODULE,
1335 .id_table = rppc_id_table,
1336 .probe = rppc_probe,
1337 .remove = rppc_remove,
1338 .callback = rppc_driver_cb,
1339};
1340
1341static int __init rppc_init(void)
1342{
1343 int ret;
1344
1345 ret = alloc_chrdev_region(&rppc_dev, 0, RPPC_MAX_DEVICES,
1346 KBUILD_MODNAME);
1347 if (ret) {
1348 pr_err("alloc_chrdev_region failed: %d\n", ret);
1349 goto out;
1350 }
1351
1352 rppc_class = class_create(THIS_MODULE, KBUILD_MODNAME);
1353 if (IS_ERR(rppc_class)) {
1354 ret = PTR_ERR(rppc_class);
1355 pr_err("class_create failed: %d\n", ret);
1356 goto unreg_region;
1357 }
1358
1359 ret = register_rpmsg_driver(&rppc_driver);
1360 if (ret) {
1361 pr_err("register_rpmsg_driver failed: %d\n", ret);
1362 goto destroy_class;
1363 }
1364 return 0;
1365
1366destroy_class:
1367 class_destroy(rppc_class);
1368unreg_region:
1369 unregister_chrdev_region(rppc_dev, RPPC_MAX_DEVICES);
1370out:
1371 return ret;
1372}
1373
1374static void __exit rppc_exit(void)
1375{
1376 unregister_rpmsg_driver(&rppc_driver);
1377 class_destroy(rppc_class);
1378 unregister_chrdev_region(rppc_dev, RPPC_MAX_DEVICES);
1379}
1380
1381module_init(rppc_init);
1382module_exit(rppc_exit);
1383MODULE_DEVICE_TABLE(rpmsg, rppc_id_table);
1384
1385MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
1386MODULE_AUTHOR("Erik Rainey <erik.rainey@ti.com>");
1387MODULE_DESCRIPTION("Remote Processor Procedure Call Driver");
1388MODULE_ALIAS("rpmsg:rpmsg-rpc");
1389MODULE_LICENSE("GPL v2");
diff --git a/drivers/rpmsg/rpmsg_rpc_dmabuf.c b/drivers/rpmsg/rpmsg_rpc_dmabuf.c
new file mode 100644
index 00000000000..2da48c4fee4
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_rpc_dmabuf.c
@@ -0,0 +1,655 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Erik Rainey <erik.rainey@ti.com>
7 * Suman Anna <s-anna@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/dma-buf.h>
20#include <linux/rpmsg_rpc.h>
21
22#include "rpmsg_rpc_internal.h"
23
24#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
25 defined(CONFIG_SOC_DRA7XX)
26/*
27 * TODO: Remove tiler_stride_from_region & rppc_recalc_off from here, and
28 * rely on OMAPDRM/TILER code for OMAP dependencies
29 */
30
31/**
32 * tiler_stride_from_region() - calculate stride value for OMAP TILER
33 * @localphys: The local physical address.
34 *
35 * Returns the stride value as seen by remote processors based on the local
36 * address given to the function. This stride value is calculated based on the
37 * actual bus address, and is assumed that the TILER regions are mapped in a
38 * in a linear fashion.
39 *
40 * The physical address range decoding of local addresses is as follows:
41 *
42 * 0x60000000 - 0x67FFFFFF : 8-bit region (Stride is 16K bytes)
43 * 0x68000000 - 0x6FFFFFFF : 16-bit region (Stride is 32K bytes)
44 * 0x70000000 - 0x77FFFFFF : 32-bit region (Stride is 32K bytes)
45 * 0x78000000 - 0x7FFFFFFF : Page mode region (Stride is 0 bytes)
46 *
47 * Return: stride value
48 */
49static long tiler_stride_from_region(phys_addr_t localphys)
50{
51 switch (localphys & 0xf8000000) {
52 case 0x60000000:
53 return 0x4000;
54 case 0x68000000:
55 case 0x70000000:
56 return 0x8000;
57 default:
58 return 0;
59 }
60}
61
62/**
63 * rppc_recalc_off() - Recalculate the unsigned offset in a buffer due to
64 * it's location in the TILER.
65 * @lpa: local physical address
66 * @uoff: unsigned offset
67 *
68 * Return: adjusted offset accounting for TILER region
69 */
70static long rppc_recalc_off(phys_addr_t lpa, long uoff)
71{
72 long stride = tiler_stride_from_region(lpa);
73
74 return (stride != 0) ? (stride * (uoff / PAGE_SIZE)) +
75 (uoff & (PAGE_SIZE - 1)) : uoff;
76}
77#else
78static inline long rppc_recalc_off(phys_addr_t lpa, long uoff)
79{
80 return uoff;
81}
82#endif
83
84/**
85 * rppc_alloc_dmabuf - import a buffer and store in a rppc buffer descriptor
86 * @rpc - rppc instance handle
87 * @fd - dma_buf file descriptor
88 * @autoreg: flag indicating the mode of creation
89 *
90 * This function primarily imports a buffer into the driver and holds
91 * a reference to the buffer on behalf of the remote processor. The
92 * buffer to be imported is represented by a dma-buf file descriptor,
93 * and as such is agnostic of the buffer allocator and/or exporter.
94 * The buffer is imported using the dma-buf api, and a driver specific
95 * buffer descriptor is used to store the imported buffer properties.
96 * The imported buffers are all stored in a rppc instance specific
97 * idr, to be used for looking up and cleaning up the driver buffer
98 * descriptors.
99 *
100 * The @autoreg field is used to dictate the manner in which the buffer
101 * is imported. The user-side can pre-register the buffers with the driver
102 * (which will import the buffers) if the application is going to use
103 * these repeatedly in consecutive function invocations. The buffers
104 * are auto-imported if the user-side has not registered them previously
105 * and are un-imported once the remote function call returns.
106 *
107 * This function is to be called only after checking that buffer has
108 * not been imported already (see rppc_find_dmabuf).
109 *
110 * Return: allocated rppc_dma_buf or error
111 */
112struct rppc_dma_buf *rppc_alloc_dmabuf(struct rppc_instance *rpc, int fd,
113 bool autoreg)
114{
115 struct rppc_device *rppcdev = rpc->rppcdev;
116 struct rppc_dma_buf *dma;
117 void *ret;
118 int id;
119
120 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
121 if (!dma)
122 return ERR_PTR(-ENOMEM);
123
124 dma->fd = fd;
125 dma->autoreg = !!autoreg;
126 dma->buf = dma_buf_get(dma->fd);
127 if (IS_ERR(dma->buf)) {
128 ret = dma->buf;
129 goto free_dma;
130 }
131
132 dma->attach = dma_buf_attach(dma->buf, rppcdev->dev);
133 if (IS_ERR(dma->attach)) {
134 ret = dma->attach;
135 goto put_buf;
136 }
137
138 dma->sgt = dma_buf_map_attachment(dma->attach, DMA_BIDIRECTIONAL);
139 if (IS_ERR(dma->sgt)) {
140 ret = dma->sgt;
141 goto detach_buf;
142 }
143
144 dma->pa = sg_dma_address(dma->sgt->sgl);
145 mutex_lock(&rpc->lock);
146 id = idr_alloc(&rpc->dma_idr, dma, 0, 0, GFP_KERNEL);
147 dma->id = id;
148 mutex_unlock(&rpc->lock);
149 if (id < 0) {
150 ret = ERR_PTR(id);
151 goto unmap_buf;
152 }
153
154 return dma;
155
156unmap_buf:
157 dma_buf_unmap_attachment(dma->attach, dma->sgt, DMA_BIDIRECTIONAL);
158detach_buf:
159 dma_buf_detach(dma->buf, dma->attach);
160put_buf:
161 dma_buf_put(dma->buf);
162free_dma:
163 kfree(dma);
164
165 return ret;
166}
167
168/**
169 * rppc_free_dmabuf - release the imported buffer
170 * @id: idr index of the imported buffer descriptor
171 * @p: imported buffer descriptor allocated during rppc_alloc_dmabuf
172 * @data: rpc instance handle
173 *
174 * This function is used to release a buffer that has been previously
175 * imported through a rppc_alloc_dmabuf call. The function can be used
176 * either individually for releasing a specific buffer or in a loop iterator
177 * for releasing all the buffers associated with a remote function call, or
178 * during cleanup of the rpc instance.
179 *
180 * Return: 0 on success, and -ENOENT if invalid pointers passed in
181 */
182int rppc_free_dmabuf(int id, void *p, void *data)
183{
184 struct rppc_dma_buf *dma = p;
185 struct rppc_instance *rpc = data;
186
187 if (!dma || !rpc)
188 return -ENOENT;
189
190 dma_buf_unmap_attachment(dma->attach, dma->sgt, DMA_BIDIRECTIONAL);
191 dma_buf_detach(dma->buf, dma->attach);
192 dma_buf_put(dma->buf);
193 WARN_ON(id != dma->id);
194 idr_remove(&rpc->dma_idr, id);
195 kfree(dma);
196
197 return 0;
198}
199
200/**
201 * rppc_free_auto_dmabuf - release an auto-registered imported buffer
202 * @id: idr index of the imported buffer descriptor
203 * @p: imported buffer descriptor allocated during the rppc_alloc_dmabuf
204 * @data: rpc instance handle
205 *
206 * This function is used to release a buffer that has been previously
207 * imported automatically in the remote function invocation path (for
208 * rppc_alloc_dmabuf invocations with autoreg set as true). The function
209 * is used as a loop iterator for releasing all such buffers associated
210 * with a remote function call, and is called after processing the
211 * translations while handling the return message of an executed function
212 * call.
213 *
214 * Return: 0 on success or if the buffer is not auto-imported, and -ENOENT
215 * if invalid pointers passed in
216 */
217static int rppc_free_auto_dmabuf(int id, void *p, void *data)
218{
219 struct rppc_dma_buf *dma = p;
220 struct rppc_instance *rpc = data;
221
222 if (WARN_ON(!dma || !rpc))
223 return -ENOENT;
224
225 if (!dma->autoreg)
226 return 0;
227
228 rppc_free_dmabuf(id, p, data);
229 return 0;
230}
231
232/**
233 * find_dma_by_fd - find the allocated buffer descriptor
234 * @id: idr loop index
235 * @p: imported buffer descriptor associated with each idr index @id
236 * @data: dma-buf file descriptor of the buffer
237 *
238 * This is a idr iterator helper function, used for checking if a buffer
239 * has been imported before and present within the rpc instance's idr.
240 *
241 * Return: rpc buffer descriptor if file descriptor matches, and 0 otherwise
242 */
243static int find_dma_by_fd(int id, void *p, void *data)
244{
245 struct rppc_dma_buf *dma = p;
246 int fd = (int)data;
247
248 if (dma->fd == fd)
249 return (int)p;
250
251 return 0;
252}
253
254/**
255 * rppc_find_dmabuf - find and return the rppc buffer descriptor of an imported
256 * buffer
257 * @rpc: rpc instance
258 * @fd: dma-buf file descriptor of the buffer
259 *
260 * This function is used to find and return the rppc buffer descriptor of an
261 * imported buffer. The function is used to check if ia buffer has already
262 * been imported (during manual registration to return an error), and to return
263 * the rppc buffer descriptor to be used for freeing (during manual
264 * deregistration). It is also used during auto-registration to see if the
265 * buffer needs to be imported through a rppc_alloc_dmabuf if not found.
266 *
267 * Return: rppc buffer descriptor of the buffer if it has already been imported,
268 * or NULL otherwise.
269 */
270struct rppc_dma_buf *rppc_find_dmabuf(struct rppc_instance *rpc, int fd)
271{
272 struct rppc_dma_buf *node = NULL;
273 void *data = (void *)fd;
274
275 dev_dbg(rpc->rppcdev->dev, "looking for fd %u\n", fd);
276
277 mutex_lock(&rpc->lock);
278 node = (struct rppc_dma_buf *)
279 idr_for_each(&rpc->dma_idr, find_dma_by_fd, data);
280 mutex_unlock(&rpc->lock);
281
282 dev_dbg(rpc->rppcdev->dev, "returning node %p for fd %u\n",
283 node, fd);
284
285 return node;
286}
287
288/**
289 * rppc_map_page - import and map a kernel page in a dma_buf
290 * @rpc - rppc instance handle
291 * @fd: file descriptor of the dma_buf to import
292 * @offset: offset of the translate location within the buffer
293 * @base_ptr: pointer for returning mapped kernel address
294 * @dmabuf: pointer for returning the imported dma_buf
295 *
296 * A helper function to import the dma_buf buffer and map into kernel
297 * the page containing the offset within the buffer. The function is
298 * called by rppc_xlate_buffers and returns the pointers to the kernel
299 * mapped address and the imported dma_buf handle in arguments. The
300 * mapping is used for performing in-place translation of the user
301 * provided pointer at location @offset within the buffer.
302 *
303 * The mapping is achieved through the appropriate dma_buf ops, and
304 * the page will be unmapped after performing the translation. See
305 * also rppc_unmap_page.
306 *
307 * Return: 0 on success, or an appropriate failure code otherwise
308 */
309static int rppc_map_page(struct rppc_instance *rpc, int fd, u32 offset,
310 uint8_t **base_ptr, struct dma_buf **dmabuf)
311{
312 int ret = 0;
313 uint8_t *ptr = NULL;
314 struct dma_buf *dbuf = NULL;
315 uint32_t pg_offset;
316 unsigned long pg_num;
317 size_t begin, end = PAGE_SIZE;
318 struct device *dev = rpc->rppcdev->dev;
319
320 if (!base_ptr || !dmabuf)
321 return -EINVAL;
322
323 pg_offset = (offset & (PAGE_SIZE - 1));
324 begin = offset & PAGE_MASK;
325 pg_num = offset >> PAGE_SHIFT;
326
327 dbuf = dma_buf_get(fd);
328 if (IS_ERR(dbuf)) {
329 ret = PTR_ERR(dbuf);
330 dev_err(dev, "invalid dma_buf file descriptor passed! fd = %d ret = %d\n",
331 fd, ret);
332 goto out;
333 }
334
335 ret = dma_buf_begin_cpu_access(dbuf, begin, end, DMA_BIDIRECTIONAL);
336 if (ret < 0) {
337 dev_err(dev, "failed to acquire cpu access to the dma buf fd = %d offset = 0x%x, ret = %d\n",
338 fd, offset, ret);
339 goto put_dmabuf;
340 }
341
342 ptr = dma_buf_kmap(dbuf, pg_num);
343 if (!ptr) {
344 ret = -ENOBUFS;
345 dev_err(dev, "failed to map the page containing the translation into kernel fd = %d offset = 0x%x\n",
346 fd, offset);
347 goto end_cpuaccess;
348 }
349
350 *base_ptr = ptr;
351 *dmabuf = dbuf;
352 dev_dbg(dev, "kmap'd base_ptr = %p buf = %p into kernel from %zu for %zu bytes, pg_offset = 0x%x\n",
353 ptr, dbuf, begin, end, pg_offset);
354 return 0;
355
356end_cpuaccess:
357 dma_buf_end_cpu_access(dbuf, begin, end, DMA_BIDIRECTIONAL);
358put_dmabuf:
359 dma_buf_put(dbuf);
360out:
361 return ret;
362}
363
364/**
365 * rppc_unmap_page - unmap and release a previously mapped page
366 * @rpc - rppc instance handle
367 * @offset: offset of the translate location within the buffer
368 * @base_ptr: kernel mapped address for the page to be unmapped
369 * @dmabuf: imported dma_buf to be released
370 *
371 * This function is called by rppc_xlate_buffers to unmap the
372 * page and release the imported buffer. It essentially undoes
373 * the functionality of rppc_map_page.
374 */
375static void rppc_unmap_page(struct rppc_instance *rpc, u32 offset,
376 uint8_t *base_ptr, struct dma_buf *dmabuf)
377{
378 uint32_t pg_offset;
379 unsigned long pg_num;
380 size_t begin, end = PAGE_SIZE;
381 struct device *dev = rpc->rppcdev->dev;
382
383 if (!base_ptr || !dmabuf)
384 return;
385
386 pg_offset = (offset & (PAGE_SIZE - 1));
387 begin = offset & PAGE_MASK;
388 pg_num = offset >> PAGE_SHIFT;
389
390 dev_dbg(dev, "Unkmaping base_ptr = %p of buf = %p from %zu to %zu bytes\n",
391 base_ptr, dmabuf, begin, end);
392 dma_buf_kunmap(dmabuf, pg_num, base_ptr);
393 dma_buf_end_cpu_access(dmabuf, begin, end, DMA_BIDIRECTIONAL);
394 dma_buf_put(dmabuf);
395}
396
397/**
398 * rppc_buffer_lookup - convert a buffer pointer to a remote processor pointer
399 * @rpc: rpc instance
400 * @uva: buffer pointer that needs to be translated
401 * @buva: base pointer of the allocated buffer
402 * @fd: dma-buf file descriptor of the allocated buffer
403 *
404 * This function is used for converting a pointer value in the function
405 * arguments to its appropriate remote processor device address value.
406 * The @uva and @buva are used for identifying the offset of the function
407 * argument pointer in an original allocation. This supports the cases where
408 * an offset pointer (eg: alignment, packed buffers etc) needs to be passed
409 * as the argument rather than the actual allocated pointer.
410 *
411 * The remote processor device address is done by retrieving the base physical
412 * address of the buffer by importing the buffer and converting it to the
413 * remote processor device address using a remoteproc api, with adjustments
414 * to the offset.
415 *
416 * The offset is specifically adjusted for OMAP TILER to account for the stride
417 * and mapping onto the remote processor.
418 *
419 * Return: remote processor device address, 0 on failure (implies invalid
420 * arguments)
421 */
422phys_addr_t rppc_buffer_lookup(struct rppc_instance *rpc, virt_addr_t uva,
423 virt_addr_t buva, int fd)
424{
425 phys_addr_t lpa = 0, rda = 0;
426 long uoff = uva - buva;
427 struct device *dev = rpc->rppcdev->dev;
428 struct rppc_dma_buf *buf;
429
430 dev_dbg(dev, "buva = %p uva = %p offset = %ld [0x%016lx] fd = %d\n",
431 (void *)buva, (void *)uva, uoff, (ulong) uoff, fd);
432
433 if (uoff < 0) {
434 dev_err(dev, "invalid pointer values for uva = %p from buva = %p\n",
435 (void *)uva, (void *)buva);
436 return rda;
437 }
438
439 buf = rppc_find_dmabuf(rpc, fd);
440 if (IS_ERR_OR_NULL(buf)) {
441 buf = rppc_alloc_dmabuf(rpc, fd, true);
442 if (IS_ERR(buf))
443 goto out;
444 }
445
446 lpa = buf->pa;
447 WARN_ON(lpa != sg_dma_address(buf->sgt->sgl));
448 uoff = rppc_recalc_off(lpa, uoff);
449 lpa += uoff;
450 rda = rppc_local_to_remote_da(rpc, lpa);
451
452out:
453 dev_dbg(dev, "host uva %p == host pa %p => remote da %p (fd %d)\n",
454 (void *)uva, (void *)lpa, (void *)rda, fd);
455 return rda;
456}
457
458/**
459 * rppc_xlate_buffers - translate argument pointers in the marshalled packet
460 * @rpc: rppc instance
461 * @func: rppc function packet being acted upon
462 * @direction: direction of translation
463 *
464 * This function translates all the pointers within the function call packet
465 * structure, based on the translation descriptor structures. The translation
466 * replaces the pointers to the appropriate pointers based on the direction.
467 * The function is invoked in preparing the packet to be sent to the remote
468 * processor-side and replaces the pointers to the remote processor device
469 * address pointers; and in processing the packet back after executing the
470 * function and replacing back the remote processor device addresses with
471 * the original pointers.
472 *
473 * Return: 0 on success, or an appropriate failure code otherwise
474 */
475int rppc_xlate_buffers(struct rppc_instance *rpc, struct rppc_function *func,
476 int direction)
477{
478 uint8_t *base_ptr = NULL;
479 struct dma_buf *dbuf = NULL;
480 struct device *dev = rpc->rppcdev->dev;
481 uint32_t ptr_idx, pri_offset, sec_offset, offset, pg_offset, size;
482 int i, limit, inc = 1;
483 virt_addr_t kva, uva, buva;
484 phys_addr_t rda;
485 int ret = 0;
486 int xlate_fd;
487
488 limit = func->num_translations;
489 if (WARN_ON(!limit))
490 return 0;
491
492 dev_dbg(dev, "operating on %d pointers\n", func->num_translations);
493
494 /* sanity check the translation elements */
495 for (i = 0; i < limit; i++) {
496 ptr_idx = func->translations[i].index;
497 pri_offset = func->params[ptr_idx].data -
498 func->params[ptr_idx].base;
499 sec_offset = func->translations[i].offset;
500 size = func->params[ptr_idx].size;
501
502 if (ptr_idx >= RPPC_MAX_PARAMETERS) {
503 dev_err(dev, "xlate[%d] - invalid parameter pointer index %u\n",
504 i, ptr_idx);
505 return -EINVAL;
506 }
507 if (func->params[ptr_idx].type != RPPC_PARAM_TYPE_PTR) {
508 dev_err(dev, "xlate[%d] - parameter index %u is not a pointer (type %u)\n",
509 i, ptr_idx, func->params[ptr_idx].type);
510 return -EINVAL;
511 }
512 if (func->params[ptr_idx].data == 0) {
513 dev_err(dev, "xlate[%d] - supplied user pointer is NULL!\n",
514 i);
515 return -EINVAL;
516 }
517 if (sec_offset > (size - sizeof(virt_addr_t))) {
518 dev_err(dev, "xlate[%d] offset is larger than data area! (sec_offset = %u size = %u)\n",
519 i, sec_offset, size);
520 return -ENOSPC;
521 }
522 }
523
524 /*
525 * we may have a failure during translation, in which case use the same
526 * loop to unwind the whole operation
527 */
528 for (i = 0; i != limit; i += inc) {
529 dev_dbg(dev, "starting translation %d of %d by %d\n",
530 i, limit, inc);
531
532 ptr_idx = func->translations[i].index;
533 pri_offset = func->params[ptr_idx].data -
534 func->params[ptr_idx].base;
535 sec_offset = func->translations[i].offset;
536 offset = pri_offset + sec_offset;
537 pg_offset = (offset & (PAGE_SIZE - 1));
538
539 /*
540 * map into kernel the page containing the offset, where the
541 * pointer needs to be translated.
542 */
543 ret = rppc_map_page(rpc, func->params[ptr_idx].fd, offset,
544 &base_ptr, &dbuf);
545 if (ret) {
546 dev_err(dev, "rppc_map_page failed, translation = %d param_index = %d fd = %d ret = %d\n",
547 i, ptr_idx, func->params[ptr_idx].fd, ret);
548 goto unwind;
549 }
550
551 /*
552 * perform the actual translation as per the direction.
553 */
554 if (direction == RPPC_UVA_TO_RPA) {
555 kva = (virt_addr_t) &(base_ptr[pg_offset]);
556 if (kva & 0x3) {
557 dev_err(dev, "kernel virtual address %p is not aligned for translation = %d\n",
558 (void *)kva, i);
559 ret = -EADDRNOTAVAIL;
560 goto unmap;
561 }
562
563 uva = *(virt_addr_t *)kva;
564 if (!uva) {
565 dev_err(dev, "user pointer in the translated offset location is NULL for translation = %d\n",
566 i);
567 print_hex_dump(KERN_DEBUG, "KMAP: ",
568 DUMP_PREFIX_NONE, 16, 1,
569 base_ptr, PAGE_SIZE, true);
570 ret = -EADDRNOTAVAIL;
571 goto unmap;
572 }
573
574 buva = (virt_addr_t) func->translations[i].base;
575 xlate_fd = func->translations[i].fd;
576
577 dev_dbg(dev, "replacing UVA %p at KVA %p prt_idx = %u pg_offset = 0x%x fd = %d\n",
578 (void *)uva, (void *)kva, ptr_idx,
579 pg_offset, xlate_fd);
580
581 /* compute the corresponding remote device address */
582 rda = rppc_buffer_lookup(rpc, uva, buva, xlate_fd);
583 if (!rda) {
584 ret = -ENODATA;
585 goto unmap;
586 }
587
588 /*
589 * replace the pointer, save the old value for replacing
590 * it back on the function return path
591 */
592 func->translations[i].fd = (int32_t) uva;
593 *(phys_addr_t *)kva = rda;
594 dev_dbg(dev, "replaced UVA %p with RDA %p at KVA %p\n",
595 (void *)uva, (void *)rda, (void *)kva);
596 } else if (direction == RPPC_RPA_TO_UVA) {
597 kva = (virt_addr_t) &(base_ptr[pg_offset]);
598 if (kva & 0x3) {
599 ret = -EADDRNOTAVAIL;
600 goto unmap;
601 }
602
603 rda = *(phys_addr_t *)kva;
604 uva = (virt_addr_t) func->translations[i].fd;
605 WARN_ON(!uva);
606 *(virt_addr_t *)kva = uva;
607
608 dev_dbg(dev, "replaced RDA %p with UVA %p at KVA %p\n",
609 (void *)rda, (void *)uva, (void *)kva);
610 }
611
612unmap:
613 /*
614 * unmap the page containing the translation from kernel, the
615 * next translation acting on the same fd might be in a
616 * different page altogether from the current one
617 */
618 rppc_unmap_page(rpc, offset, base_ptr, dbuf);
619 dbuf = NULL;
620 base_ptr = NULL;
621
622 if (!ret)
623 continue;
624
625unwind:
626 /*
627 * unwind all the previous translations if the failure occurs
628 * while sending a message to the remote-side. There's nothing
629 * to do but to continue if the failure occurs during the
630 * processing of a function response.
631 */
632 if (direction == RPPC_UVA_TO_RPA) {
633 dev_err(dev, "unwinding UVA to RDA translations! translation = %d\n",
634 i);
635 direction = RPPC_RPA_TO_UVA;
636 inc = -1;
637 limit = -1;
638 } else if (direction == RPPC_RPA_TO_UVA) {
639 dev_err(dev, "error during UVA to RDA translations!! current translation = %d\n",
640 i);
641 }
642 }
643
644 /*
645 * all the in-place pointer replacements are done, release all the
646 * imported buffers during the remote function return path
647 */
648 if (direction == RPPC_RPA_TO_UVA) {
649 mutex_lock(&rpc->lock);
650 idr_for_each(&rpc->dma_idr, rppc_free_auto_dmabuf, rpc);
651 mutex_unlock(&rpc->lock);
652 }
653
654 return ret;
655}
diff --git a/drivers/rpmsg/rpmsg_rpc_internal.h b/drivers/rpmsg/rpmsg_rpc_internal.h
new file mode 100644
index 00000000000..ea787101375
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_rpc_internal.h
@@ -0,0 +1,416 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name Texas Instruments nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _RPMSG_RPC_INTERNAL_H_
34#define _RPMSG_RPC_INTERNAL_H_
35
36#include <linux/cdev.h>
37#include <linux/idr.h>
38#include <linux/wait.h>
39#include <linux/fs.h>
40#include <linux/skbuff.h>
41
42#ifdef CONFIG_PHYS_ADDR_T_64BIT
43typedef u64 virt_addr_t;
44#else
45typedef u32 virt_addr_t;
46#endif
47
48/**
49 * struct rppc_device - The per-device (server) data
50 * @cdev: character device
51 * @dev: device
52 * @rpdev: rpmsg channel device associated with the remote server
53 * @instances: list of currently opened/connected instances
54 * @lock: mutex for protection of device variables
55 * @comp: completion signal used for unblocking users during a
56 * remote processor recovery
57 * @sig_attr: array of device attributes to use with the publishing of
58 * function information in sysfs for all the functions
59 * associated with this remote server device.
60 * @signatures: function signatures for the functions published by this
61 * remote server device
62 * @minor: minor number for the character device
63 * @num_funcs: number of functions published by this remote server device
64 * @cur_func: counter used while querying information for each function
65 * associated with this remote server device
66 *
67 * A rppc_device indicates the base remote server device that supports the
68 * execution of a bunch of remote functions. Each such remote server device
69 * has an associated character device that is used by the userland apps to
70 * connect to it, and request the execution of any of these remote functions.
71 */
72struct rppc_device {
73 struct cdev cdev;
74 struct device *dev;
75 struct rpmsg_channel *rpdev;
76 struct list_head instances;
77 struct mutex lock;
78 struct completion comp;
79 struct device_attribute *sig_attr;
80 struct rppc_func_signature *signatures;
81 unsigned int minor;
82 u32 num_funcs;
83 u32 cur_func;
84};
85
86/**
87 * struct rppc_instance - The per-instance data structure (per user)
88 * @list: list node
89 * @rppcdev: the rppc device (remote server instance) handle
90 * @queue: queue of buffers waiting to be read by the user
91 * @lock: mutex for protecting instance variables
92 * @readq: wait queue of blocked user threads waiting to read data
93 * @reply_arrived: signal for unblocking the user thread
94 * @ept: rpmsg endpoint associated with the rppc device
95 * @in_transition: flag for storing a pending connection request
96 * @dst: destination end-point of the remote server instance
97 * @state: state of the opened instance, see enum rppc_state
98 * @dma_idr: idr structure storing the imported buffers
99 * @msg_id: last/current active message id tagged on a message sent
100 * to the remote processor
101 * @fxn_list: list of functions published by the remote server instance
102 *
103 * This structure is created whenever the user opens the driver. The
104 * various elements of the structure are used to store its state and
105 * information about the remote server it is connected to.
106 */
107struct rppc_instance {
108 struct list_head list;
109 struct rppc_device *rppcdev;
110 struct sk_buff_head queue;
111 struct mutex lock;
112 wait_queue_head_t readq;
113 struct completion reply_arrived;
114 struct rpmsg_endpoint *ept;
115 int in_transition;
116 u32 dst;
117 int state;
118 struct idr dma_idr;
119 u16 msg_id;
120 struct list_head fxn_list;
121};
122
123/**
124 * struct rppc_function_list - outstanding function descriptor
125 * @list: list node
126 * @function: current remote function descriptor
127 * @msg_id: message id for the function invocation
128 *
129 * This structure is used for storing the information about outstanding
130 * functions that the remote side is executing. This provides the host
131 * side a means to track every outstanding function, and a means to process
132 * the responses received from the remote processor.
133 */
134struct rppc_function_list {
135 struct list_head list;
136 struct rppc_function *function;
137 u16 msg_id;
138};
139
140/**
141 * struct rppc_dma_buf - a rppc dma_buf descriptor for buffers imported by rppc
142 * @fd: file descriptor of a buffer used to import the dma_buf
143 * @id: idr index value for this descriptor
144 * @buf: imported dma_buf handle for the buffer
145 * @attach: attachment structure returned by exporter upon attaching to
146 * the buffer by the rppc driver
147 * @sgt: the scatter-gather structure associated with @buf
148 * @pa: the physical address associated with the imported buffer
149 * @autoreg: mode of how the descriptor is created
150 *
151 * This structure is used for storing the information relevant to the imported
152 * buffer. The rpmsg rpc driver acts as a proxy on behalf of the remote core
153 * and attaches itself to the driver while the remote processor/accelerators are
154 * operating on the buffer.
155 */
156struct rppc_dma_buf {
157 int fd;
158 int id;
159 struct dma_buf *buf;
160 struct dma_buf_attachment *attach;
161 struct sg_table *sgt;
162 phys_addr_t pa;
163 int autoreg;
164};
165
166/**
167 * enum rppc_msg_type - message types exchanged between host and remote server
168 * @RPPC_MSGTYPE_DEVINFO_REQ: request remote server for channel information
169 * @RPPC_MSGTYPE_DEVINFO_RESP: response message from remote server for a
170 * request of type RPPC_MSGTYPE_DEVINFO_REQ
171 * @RPPC_MSGTYPE_FUNCTION_QUERY: request remote server for information about a
172 * specific function
173 * @RPPC_MSGTYPE_FUNCTION_INFO: response message from remote server for a prior
174 * request of type RPPC_MSGTYPE_FUNCTION_QUERY
175 * @RPPC_MSGTYPE_CREATE_REQ: request the remote server manager to create a new
176 * remote server instance. No secondary data is
177 * needed
178 * @RPPC_MSGTYPE_CREATE_RESP: response message from remote server manager for a
179 * request of type RPPC_MSGTYPE_CREATE_REQ. The
180 * message contains the new endpoint address in the
181 * rppc_instance_handle
182 * @RPPC_MSGTYPE_DELETE_REQ: request the remote server manager to delete a
183 * remote server instance
184 * @RPPC_MSGTYPE_DELETE_RESP: response message from remote server manager to a
185 * request of type RPPC_MSGTYPE_DELETE_REQ. The
186 * message contains the old endpoint address in the
187 * rppc_instance_handle
188 * @RPPC_MSGTYPE_FUNCTION_CALL: request remote server to execute a specific
189 * function
190 * @RPPC_MSGTYPE_FUNCTION_RET: response message carrying the return status of a
191 * specific function execution
192 * @RPPC_MSGTYPE_ERROR: an error response message sent by either the remote
193 * server manager or remote server instance while
194 * processing any request messages
195 * @RPPC_MSGTYPE_MAX: limit value to define the maximum message type value
196 *
197 * Every message exchanged between the host-side and the remote-side is
198 * identified through a message type defined in this enum. The message type
199 * is specified through the msg_type field of the struct rppc_msg_header,
200 * which is the common header for rppc messages.
201 */
202enum rppc_msg_type {
203 RPPC_MSGTYPE_DEVINFO_REQ = 0,
204 RPPC_MSGTYPE_DEVINFO_RESP = 1,
205 RPPC_MSGTYPE_FUNCTION_QUERY = 2,
206 RPPC_MSGTYPE_FUNCTION_INFO = 3,
207 RPPC_MSGTYPE_CREATE_REQ = 6,
208 RPPC_MSGTYPE_CREATE_RESP = 8,
209 RPPC_MSGTYPE_DELETE_REQ = 4,
210 RPPC_MSGTYPE_DELETE_RESP = 7,
211 RPPC_MSGTYPE_FUNCTION_CALL = 5,
212 RPPC_MSGTYPE_FUNCTION_RET = 9,
213 RPPC_MSGTYPE_ERROR = 10,
214 RPPC_MSGTYPE_MAX
215};
216
217/**
218 * enum rppc_infotype - function information query type
219 * @RPPC_INFOTYPE_FUNC_SIGNATURE: function signature
220 * @RPPC_INFOTYPE_NUM_CALLS: the number of times a function has been invoked
221 * @RPPC_INFOTYPE_MAX: limit value to define the maximum info type
222 *
223 * This enum is used for identifying the type of information queried
224 * from the remote processor. Only RPPC_INFOTYPE_FUNC_SIGNATURE is
225 * currently used.
226 */
227enum rppc_infotype {
228 RPPC_INFOTYPE_FUNC_SIGNATURE = 1,
229 RPPC_INFOTYPE_NUM_CALLS,
230 RPPC_INFOTYPE_MAX
231};
232
233/**
234 * struct rppc_instance_handle - rppc instance information
235 * @endpoint_address: end-point address of the remote server instance
236 * @status: status of the request
237 *
238 * This structure indicates the format of the message payload exchanged
239 * between the host and the remote sides for messages pertaining to
240 * creation and deletion of the remote server instances. This payload
241 * is associated with messages of type RPPC_MSGTYPE_CREATE_RESP and
242 * RPPC_MSGTYPE_DELETE_RESP.
243 */
244struct rppc_instance_handle {
245 uint32_t endpoint_address;
246 uint32_t status;
247} __packed;
248
249/**
250 * struct rppc_param_signature - parameter descriptor
251 * @direction: input or output classifier, see enum rppc_param_direction
252 * @type: parameter data type, see enum rppc_param_type
253 * @count: used to do some basic sanity checking on array bounds
254 */
255struct rppc_param_signature {
256 uint32_t direction;
257 uint32_t type;
258 uint32_t count;
259};
260
261/**
262 * struct rppc_func_signature - remote function signature descriptor
263 * @name: name of the function
264 * @num_param: number of parameters to the function
265 * @params: parameter descriptors for each of the parameters
266 *
267 * This structure contains the indicates the format of the message payload
268 * exchanged between the host and the remote sides for messages pertaining
269 * to creation and deletion of the remote server instances. This payload
270 * is associated with messages of type RPPC_MSGTYPE_CREATE_RESP and
271 * RPPC_MSGTYPE_FUNCTION_INFO.
272 */
273struct rppc_func_signature {
274 char name[RPPC_MAX_CHANNEL_NAMELEN];
275 uint32_t num_param;
276 struct rppc_param_signature params[RPPC_MAX_NUM_PARAMS + 1];
277};
278
279/**
280 * struct rppc_query_function - function info packet structure
281 * @info_type: type of the function information requested, see
282 * enum rppc_infotype
283 * @fxn_id: function identifier on this specific remote server instance
284 * @num_calls: number of types function is invoked, filled in during a response
285 * (only valid for rppc_infotype RPPC_INFOTYPE_NUM_CALLS)
286 * @signature: the signature of the function including its return type,
287 * parameters and thier description
288 * (only valid for rppc_infotype RPPC_INFOTYPE_FUNC_SIGNATURE)
289 *
290 * This structure indicates the format of the message payload exchanged
291 * between the host and the remote sides for messages pertaining to
292 * information about each function supported by the remote server instance.
293 * This payload is associated with messages of type RPPC_MSGTYPE_FUNCTION_QUERY
294 * and RPPC_MSGTYPE_FUNCTION_INFO.
295 */
296struct rppc_query_function {
297 uint32_t info_type;
298 uint32_t fxn_id;
299 union {
300 uint32_t num_calls;
301 struct rppc_func_signature signature;
302 } info;
303};
304
305/**
306 * enum rppc_translate_direction - pointer translation direction
307 * @RPPC_UVA_TO_RPA: user virtual address to remote device address translation
308 * @RPPC_RPA_TO_UVA: remote device address to user virtual address translation
309 *
310 * An enum used for identifying the rppc function message direction, whether
311 * it is going to the remote side, or is a response from the remote side. This
312 * is used in translating the pointers from the host-side to the remote-side
313 * and vice versa depending on the packet direction.
314 */
315enum rppc_translate_direction {
316 RPPC_UVA_TO_RPA,
317 RPPC_RPA_TO_UVA,
318};
319
320/**
321 * enum rppc_state - rppc instance state
322 * @RPPC_STATE_DISCONNECTED: uninitialized state
323 * @RPPC_STATE_CONNECTED: initialized state
324 * @RPPC_STATE_STALE: invalid or stale state
325 * @RPPC_STATE_MAX: limit value for the different state values
326 *
327 * This enum value is used to define the status values of a
328 * rppc_instance object.
329 */
330enum rppc_state {
331 RPPC_STATE_DISCONNECTED,
332 RPPC_STATE_CONNECTED,
333 RPPC_STATE_STALE,
334 RPPC_STATE_MAX
335};
336
337/**
338 * struct rppc_device_info - rppc remote server device info
339 * @num_funcs: number of functions supported by a remote server instance
340 *
341 * This structure indicates the format of the message payload responded by
342 * the remote side upon a request for message type RPPC_MSGTYPE_DEVINFO_REQ.
343 * This payload is associated with messages of type RPPC_MSGTYPE_DEVINFO_RESP.
344 */
345struct rppc_device_info {
346 uint32_t num_funcs;
347};
348
349/**
350 * struct rppc_error - rppc error information
351 * @endpoint_address: end-point address of the remote server instance
352 * @status: status of the request
353 *
354 * This structure indicates the format of the message payload exchanged
355 * between the host and the remote sides for error messages. This payload
356 * is associated with messages of type RPPC_MSGTYPE_ERROR
357 * XXX: check if this is needed still, not used anywhere at present
358 */
359struct rppc_error {
360 uint32_t endpoint_address;
361 uint32_t status;
362} __packed;
363
364/**
365 * struct rppc_param_data - marshalled parameter data structure
366 * @size: size of the parameter data type
367 * @data: actual parameter data
368 *
369 * Each function parameter is marshalled in this form between the host
370 * and remote sides. The @data field would contain the actual value of
371 * of the parameter if it is a scalar argument type, or the remote-side
372 * device address (virtual address) of the pointer if the argument is
373 * of pointer type.
374 */
375struct rppc_param_data {
376 size_t size;
377 size_t data;
378} __packed;
379
380/**
381 * struct rppc_msg_header - generic rpmsg rpc message header
382 * @msg_type: message type, see enum rppc_msg_type
383 * @msg_len: length of the message payload in bytes
384 * @msg_data: the actual message payload (depends on message type)
385 *
386 * All RPPC messages will start with this common header (which will begin
387 * right after the standard rpmsg header ends).
388 */
389struct rppc_msg_header {
390 uint32_t msg_type;
391 uint32_t msg_len;
392 uint8_t msg_data[0];
393} __packed;
394
395#define RPPC_PAYLOAD(ptr, type) \
396 ((struct type *)&(ptr)[sizeof(struct rppc_msg_header)])
397
398
399/* from rpmsg_rpc.c */
400phys_addr_t rppc_local_to_remote_da(struct rppc_instance *rpc, phys_addr_t pa);
401
402/* from rpmsg_rpc_dmabuf.c */
403struct rppc_dma_buf *rppc_alloc_dmabuf(struct rppc_instance *rpc,
404 int fd, bool autoreg);
405struct rppc_dma_buf *rppc_find_dmabuf(struct rppc_instance *rpc, int fd);
406int rppc_free_dmabuf(int id, void *p, void *data);
407phys_addr_t rppc_buffer_lookup(struct rppc_instance *rpc, virt_addr_t uva,
408 virt_addr_t buva, int fd);
409int rppc_xlate_buffers(struct rppc_instance *rpc, struct rppc_function *func,
410 int direction);
411
412/* from rpmsg_rpc_sysfs.c */
413int rppc_create_sysfs(struct rppc_device *rppcdev);
414int rppc_remove_sysfs(struct rppc_device *rppcdev);
415
416#endif
diff --git a/drivers/rpmsg/rpmsg_rpc_sysfs.c b/drivers/rpmsg/rpmsg_rpc_sysfs.c
new file mode 100644
index 00000000000..da0e3275e47
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_rpc_sysfs.c
@@ -0,0 +1,255 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Erik Rainey <erik.rainey@ti.com>
7 * Suman Anna <s-anna@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/device.h>
20#include <linux/slab.h>
21#include <linux/rpmsg_rpc.h>
22
23#include "rpmsg_rpc_internal.h"
24
25static ssize_t show_numfuncs(struct device *dev, struct device_attribute *attr,
26 char *buf)
27{
28 struct rppc_device *rppcdev = dev_get_drvdata(dev);
29 return snprintf(buf, PAGE_SIZE, "%u\n", rppcdev->num_funcs - 1);
30}
31
32static ssize_t set_type_c(char *buf, uint32_t len,
33 struct rppc_param_signature *psig)
34{
35 char *isptr = (psig->type & RPPC_PARAM_PTR ? " *" : "");
36
37 switch (psig->type & RPPC_PARAM_MASK) {
38 case RPPC_PARAM_S08:
39 return snprintf(buf, len, "int8_t%s", isptr);
40 case RPPC_PARAM_U08:
41 return snprintf(buf, len, "uint8_t%s", isptr);
42 case RPPC_PARAM_S16:
43 return snprintf(buf, len, "int16_t%s", isptr);
44 case RPPC_PARAM_U16:
45 return snprintf(buf, len, "uint16_t%s", isptr);
46 case RPPC_PARAM_S32:
47 return snprintf(buf, len, "int32_t%s", isptr);
48 case RPPC_PARAM_U32:
49 return snprintf(buf, len, "uint32_t%s", isptr);
50 case RPPC_PARAM_S64:
51 return snprintf(buf, len, "int64_t%s", isptr);
52 case RPPC_PARAM_U64:
53 return snprintf(buf, len, "uint64_t%s", isptr);
54 default:
55 return snprintf(buf, len, "<unknown>%s", isptr);
56 }
57}
58
59static ssize_t set_type_doxy(char *buf, uint32_t len,
60 struct rppc_param_signature *psig)
61{
62 char *isptr = (psig->type & RPPC_PARAM_PTR ? " *" : "");
63 char dir[10];
64
65 switch (psig->direction) {
66 case RPPC_PARAMDIR_IN:
67 snprintf(dir, sizeof(dir), "[in]");
68 break;
69 case RPPC_PARAMDIR_OUT:
70 snprintf(dir, sizeof(dir), "[out]");
71 break;
72 case RPPC_PARAMDIR_BI:
73 snprintf(dir, sizeof(dir), "[in,out]");
74 break;
75 default:
76 snprintf(dir, sizeof(dir), "[unknown]");
77 break;
78 }
79
80 switch (psig->type & RPPC_PARAM_MASK) {
81 case RPPC_PARAM_S08:
82 return snprintf(buf, len, "%s int8_t%s", dir, isptr);
83 case RPPC_PARAM_U08:
84 return snprintf(buf, len, "%s uint8_t%s", dir, isptr);
85 case RPPC_PARAM_S16:
86 return snprintf(buf, len, "%s int16_t%s", dir, isptr);
87 case RPPC_PARAM_U16:
88 return snprintf(buf, len, "%s uint16_t%s", dir, isptr);
89 case RPPC_PARAM_S32:
90 return snprintf(buf, len, "%s int32_t%s", dir, isptr);
91 case RPPC_PARAM_U32:
92 return snprintf(buf, len, "%s uint32_t%s", dir, isptr);
93 case RPPC_PARAM_S64:
94 return snprintf(buf, len, "%s int64_t%s", dir, isptr);
95 case RPPC_PARAM_U64:
96 return snprintf(buf, len, "%s uint64_t%s", dir, isptr);
97 default:
98 return snprintf(buf, len, "%s <unknown>%s", dir, isptr);
99 }
100}
101
102static ssize_t show_c_function(struct device *dev,
103 struct device_attribute *attr, char *buf)
104{
105 struct rppc_device *rppcdev = dev_get_drvdata(dev);
106 char return_value[11]; /* longest string is strlen("uintXX_t *") = 10 */
107 char parameters[110]; /* longest string * 10 + 9(,) */
108 char comment[300];
109 int p;
110 ssize_t pidx = 0;
111 ssize_t cidx = 0;
112 __u32 index = 0;
113
114 if (sscanf(attr->attr.name, "c_function%u\n", &index) != 1)
115 return -EIO;
116
117 memset(return_value, 0, sizeof(return_value));
118 memset(parameters, 0, sizeof(parameters));
119
120 strcpy(return_value, "void");
121 strcpy(parameters, "void");
122 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx, "/**\n");
123 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx,
124 " * \\fn %s\n", rppcdev->signatures[index].name);
125 for (p = 0; p < rppcdev->signatures[index].num_param; p++) {
126 if (p == 0) {
127 set_type_c(return_value, sizeof(return_value),
128 &rppcdev->signatures[index].params[0]);
129 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx,
130 " * \\return %s\n", return_value);
131 } else {
132 pidx += set_type_c(&parameters[pidx],
133 sizeof(parameters) - pidx,
134 &rppcdev->signatures[index].params[p]);
135 if (p != rppcdev->signatures[index].num_param - 1)
136 parameters[pidx++] = ',';
137 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx,
138 " * \\param ");
139 cidx += set_type_doxy(&comment[cidx],
140 sizeof(comment) - cidx,
141 &rppcdev->signatures[index].params[p]);
142 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx,
143 "\n");
144 }
145 }
146 if (p <= 1)
147 pidx += strlen("void");
148 if (pidx < sizeof(parameters))
149 parameters[pidx] = '\0';
150 cidx += snprintf(&comment[cidx], sizeof(comment) - cidx, " */");
151 return snprintf(buf, PAGE_SIZE, "%s\nextern \"C\" %s %s(%s);\n",
152 comment, return_value, rppcdev->signatures[index].name,
153 parameters);
154}
155
156static struct device_attribute rppc_attrs[] = {
157 __ATTR(num_funcs, S_IRUGO, show_numfuncs, NULL),
158};
159
160/**
161 * rppc_create_sysfs - Creates the sysfs entry structures for the instance
162 * @rppcdev: the rppc device (remote server instance) handle
163 *
164 * Helper function to create all the sysfs entries associated with a rppc
165 * device. Each device is associated with a number of remote procedure
166 * functions. The number of such functions and the signatures of those
167 * functions are created in sysfs. Function is invoked after querying
168 * the remote side about the supported functions on this device.
169 *
170 * The entries are split into a set of static entries, which are common
171 * between all rppc devices, and a set of dynamic entries specific to
172 * each rppc device.
173 *
174 * Return: 0 on success, or an appropriate error code otherwise
175 */
176int rppc_create_sysfs(struct rppc_device *rppcdev)
177{
178 int i;
179 int ret;
180
181 rppcdev->sig_attr = kzalloc(sizeof(*rppcdev->sig_attr) *
182 rppcdev->num_funcs, GFP_KERNEL);
183 if (!rppcdev->sig_attr)
184 return -ENOMEM;
185
186 for (i = 0; i < ARRAY_SIZE(rppc_attrs); i++) {
187 ret = device_create_file(rppcdev->dev, &rppc_attrs[i]);
188 if (ret) {
189 dev_err(rppcdev->dev, "failed to create sysfs entry\n");
190 goto clean_static_entries;
191 }
192 }
193
194 for (i = 1; i < rppcdev->num_funcs; i++) {
195 sysfs_attr_init(&rppcdev->sig_attr[i].attr);
196 rppcdev->sig_attr[i].attr.name =
197 kzalloc(RPPC_MAX_FUNC_NAMELEN, GFP_KERNEL);
198 if (!rppcdev->sig_attr[i].attr.name) {
199 ret = -ENOMEM;
200 goto clean_dynamic_entries;
201 }
202 snprintf((char *)rppcdev->sig_attr[i].attr.name,
203 RPPC_MAX_FUNC_NAMELEN, "c_function%u", i);
204 rppcdev->sig_attr[i].attr.mode = S_IRUGO;
205 rppcdev->sig_attr[i].show = show_c_function;
206 rppcdev->sig_attr[i].store = NULL;
207
208 ret = device_create_file(rppcdev->dev, &rppcdev->sig_attr[i]);
209 if (ret) {
210 dev_err(rppcdev->dev, "failed to create sysfs function entry (%d)\n",
211 ret);
212 goto clean_dynamic_entries;
213 }
214 }
215 return 0;
216
217clean_dynamic_entries:
218 while (i-- > 1) {
219 device_remove_file(rppcdev->dev, &rppcdev->sig_attr[i]);
220 kfree(rppcdev->sig_attr[i].attr.name);
221 }
222 i = ARRAY_SIZE(rppc_attrs);
223clean_static_entries:
224 while (i-- > 0)
225 device_remove_file(rppcdev->dev, &rppc_attrs[i]);
226 kfree(rppcdev->sig_attr);
227 return ret;
228}
229
230/**
231 * rppc_remove_sysfs: Removes the sysfs entry structures for the instance
232 * @rppcdev: the rppc device (remote server instance) handle
233 *
234 * Helper function to remove all the sysfs entries associated with the
235 * rppc device.
236 *
237 * Return: 0 on success, or an appropriate error code otherwise
238 */
239int rppc_remove_sysfs(struct rppc_device *rppcdev)
240{
241 int i;
242
243 if (rppcdev->sig_attr) {
244 for (i = 1; i < rppcdev->num_funcs; i++) {
245 device_remove_file(rppcdev->dev, &rppcdev->sig_attr[i]);
246 kfree(rppcdev->sig_attr[i].attr.name);
247 }
248 }
249 kfree(rppcdev->sig_attr);
250
251 for (i = 0; i < ARRAY_SIZE(rppc_attrs); i++)
252 device_remove_file(rppcdev->dev, &rppc_attrs[i]);
253
254 return 0;
255}
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 3dcf8b4269a..4ce5f43a54a 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -502,7 +502,7 @@ static int rpmsg_channel_match(struct device *dev, void *data)
502 * this function will be used to create both static and dynamic 502 * this function will be used to create both static and dynamic
503 * channels. 503 * channels.
504 */ 504 */
505static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp, 505static struct rpmsg_channel *__rpmsg_create_channel(struct virtproc_info *vrp,
506 struct rpmsg_channel_info *chinfo) 506 struct rpmsg_channel_info *chinfo)
507{ 507{
508 struct rpmsg_channel *rpdev; 508 struct rpmsg_channel *rpdev;
@@ -556,11 +556,42 @@ static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
556 return rpdev; 556 return rpdev;
557} 557}
558 558
559/**
560 * rpmsg_create_channel - create a rpmsg channel using its name, desc, id and
561 * address
562 * @vrp: the virtual processor on which this channel is being created
563 * @name: name of the rpmsg channel
564 * @desc: description of the rpmsg channel
565 * @src: source end-point address for the channel
566 * @dst: destination end-point address for the channel
567 *
568 * This function provides a means to create new rpmsg channels on a particular
569 * virtual processor. The caller supplies the address info, name and descriptor
570 * for the channel. This is useful when creating channels from the host side.
571 *
572 * Return: a pointer to a newly created rpmsg channel device on success,
573 * or NULL on failure
574 */
575struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
576 const char *name, const char *desc,
577 int src, int dst)
578{
579 struct rpmsg_channel_info chinfo;
580
581 strncpy(chinfo.name, name, sizeof(chinfo.name));
582 strncpy(chinfo.desc, desc, sizeof(chinfo.desc));
583 chinfo.src = src;
584 chinfo.dst = dst;
585
586 return __rpmsg_create_channel(vrp, &chinfo);
587}
588EXPORT_SYMBOL(rpmsg_create_channel);
589
559/* 590/*
560 * find an existing channel using its name + address properties, 591 * find an existing channel using its name + address properties,
561 * and destroy it 592 * and destroy it
562 */ 593 */
563static int rpmsg_destroy_channel(struct virtproc_info *vrp, 594static int __rpmsg_destroy_channel(struct virtproc_info *vrp,
564 struct rpmsg_channel_info *chinfo) 595 struct rpmsg_channel_info *chinfo)
565{ 596{
566 struct virtio_device *vdev = vrp->vdev; 597 struct virtio_device *vdev = vrp->vdev;
@@ -577,6 +608,34 @@ static int rpmsg_destroy_channel(struct virtproc_info *vrp,
577 return 0; 608 return 0;
578} 609}
579 610
611/**
612 * rpmsg_destroy_channel - destroy a rpmsg channel
613 * @rpdev: rpmsg channel to be destroyed
614 *
615 * This function is the primary means to destroy a rpmsg channel that was
616 * created from the host-side. This API is strictly intended to be used only
617 * for channels created using the rpmsg_create_channel API.
618 *
619 * Return: 0 on success, or a failure code otherwise
620 */
621int rpmsg_destroy_channel(struct rpmsg_channel *rpdev)
622{
623 struct device *dev;
624 struct virtio_device *vdev = rpmsg_get_virtio_dev(rpdev);
625
626 if (!rpdev || !vdev)
627 return -EINVAL;
628
629 dev = &rpdev->dev;
630 if (dev->bus != &rpmsg_bus || dev->parent != &vdev->dev)
631 return -EINVAL;
632
633 device_unregister(dev);
634
635 return 0;
636}
637EXPORT_SYMBOL(rpmsg_destroy_channel);
638
580/* super simple buffer "allocator" that is just enough for now */ 639/* super simple buffer "allocator" that is just enough for now */
581static void *get_a_tx_buf(struct virtproc_info *vrp) 640static void *get_a_tx_buf(struct virtproc_info *vrp)
582{ 641{
@@ -789,6 +848,22 @@ out:
789} 848}
790EXPORT_SYMBOL(rpmsg_send_offchannel_raw); 849EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
791 850
851/**
852 * rpmsg_get_virtio_dev - Get underlying virtio device
853 * @rpdev: the rpmsg channel
854 *
855 * Returns the underlying remoteproc virtio device, if one exists. Returns NULL
856 * otherwise.
857 */
858struct virtio_device *rpmsg_get_virtio_dev(struct rpmsg_channel *rpdev)
859{
860 if (!rpdev || !rpdev->vrp)
861 return NULL;
862
863 return rpdev->vrp->vdev;
864}
865EXPORT_SYMBOL(rpmsg_get_virtio_dev);
866
792static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev, 867static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
793 struct rpmsg_hdr *msg, unsigned int len) 868 struct rpmsg_hdr *msg, unsigned int len)
794{ 869{
@@ -948,13 +1023,14 @@ static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
948 chinfo.dst = msg->addr; 1023 chinfo.dst = msg->addr;
949 1024
950 if (msg->flags & RPMSG_NS_DESTROY) { 1025 if (msg->flags & RPMSG_NS_DESTROY) {
951 ret = rpmsg_destroy_channel(vrp, &chinfo); 1026 ret = __rpmsg_destroy_channel(vrp, &chinfo);
952 if (ret) 1027 if (ret)
953 dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); 1028 dev_err(dev, "__rpmsg_destroy_channel failed: %d\n",
1029 ret);
954 } else { 1030 } else {
955 newch = rpmsg_create_channel(vrp, &chinfo); 1031 newch = __rpmsg_create_channel(vrp, &chinfo);
956 if (!newch) 1032 if (!newch)
957 dev_err(dev, "rpmsg_create_channel failed\n"); 1033 dev_err(dev, "__rpmsg_create_channel failed\n");
958 } 1034 }
959} 1035}
960 1036
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
index ec1b7fbd993..fe00b06536f 100644
--- a/include/linux/rpmsg.h
+++ b/include/linux/rpmsg.h
@@ -180,6 +180,11 @@ struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *,
180 rpmsg_rx_cb_t cb, void *priv, u32 addr); 180 rpmsg_rx_cb_t cb, void *priv, u32 addr);
181int 181int
182rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); 182rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool);
183struct virtio_device *rpmsg_get_virtio_dev(struct rpmsg_channel *rpdev);
184struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
185 const char *name, const char *desc,
186 int src, int dst);
187int rpmsg_destroy_channel(struct rpmsg_channel *rpdev);
183 188
184/** 189/**
185 * rpmsg_send() - send a message across to the remote processor 190 * rpmsg_send() - send a message across to the remote processor
diff --git a/include/linux/rpmsg_rpc.h b/include/linux/rpmsg_rpc.h
new file mode 100644
index 00000000000..5141c34d829
--- /dev/null
+++ b/include/linux/rpmsg_rpc.h
@@ -0,0 +1,105 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name Texas Instruments nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _LINUX_RPMSG_RPC_H_
34#define _LINUX_RPMSG_RPC_H_
35
36#include <uapi/linux/rpmsg_rpc.h>
37
38#define RPPC_MAX_NUM_FUNCS (1024)
39#define RPPC_MAX_CHANNEL_NAMELEN (64)
40#define RPPC_MAX_FUNC_NAMELEN (64)
41#define RPPC_MAX_NUM_PARAMS (10)
42
43/**
44 * enum rppc_param_direction - direction of the function parameter
45 * @RPPC_PARAMDIR_IN: input argument
46 * @RPPC_PARAMDIR_OUT: output argument
47 * @RPPC_PARAMDIR_BI: an in and out argument
48 * @RPPC_PARAMDIR_MAX: limit value for the direction type
49 *
50 * The parameter direction is described as relative to the function.
51 */
52enum rppc_param_direction {
53 RPPC_PARAMDIR_IN = 0,
54 RPPC_PARAMDIR_OUT,
55 RPPC_PARAMDIR_BI,
56 RPPC_PARAMDIR_MAX
57};
58
59/**
60 * enum rppc_param_datatype - parameter data type and descriptor flags
61 * @RPPC_PARAM_VOID: parameter is of type 'void'
62 * @RPPC_PARAM_S08: parameter is of type 's8'
63 * @RPPC_PARAM_U08: parameter is of type 'u8'
64 * @RPPC_PARAM_S16: parameter is of type 's16'
65 * @RPPC_PARAM_U16: parameter is of type 'u16'
66 * @RPPC_PARAM_S32: parameter is of type 's32'
67 * @RPPC_PARAM_U32: parameter is of type 'u32'
68 * @RPPC_PARAM_S64: parameter is of type 's64'
69 * @RPPC_PARAM_U64: parameter is of type 'u64'
70 * @RPPC_PARAM_ATOMIC_MAX: limit value for scalar data types
71 * @RPPC_PARAM_MASK: mask field for retrieving the scalar data type
72 * @RPPC_PARAM_PTR: flag to indicate the data type is a pointer
73 * @RPPC_PARAM_MAX: max limit value used as a marker
74 *
75 * This enum is used to describe the data type for the parameters.
76 * A pointer of a data type is reflected by using an additional bit
77 * mask field.
78 */
79enum rppc_param_datatype {
80 RPPC_PARAM_VOID = 0,
81 RPPC_PARAM_S08,
82 RPPC_PARAM_U08,
83 RPPC_PARAM_S16,
84 RPPC_PARAM_U16,
85 RPPC_PARAM_S32,
86 RPPC_PARAM_U32,
87 RPPC_PARAM_S64,
88 RPPC_PARAM_U64,
89 RPPC_PARAM_ATOMIC_MAX,
90
91 RPPC_PARAM_MASK = 0x7F,
92 RPPC_PARAM_PTR = 0x80,
93
94 RPPC_PARAM_MAX
95};
96
97/*
98 * helper macros to deal with parameter types
99 */
100#define RPPC_PTR_TYPE(type) ((type) | RPPC_PARAM_PTR)
101#define RPPC_IS_PTR(type) ((type) & RPPC_PARAM_PTR)
102#define RPPC_IS_ATOMIC(type) (((type) > RPPC_PARAM_VOID) && \
103 ((type) < RPPC_PARAM_ATOMIC_MAX))
104
105#endif /* _LINUX_RPMSG_RPC_H_ */
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 8e98297f138..32f4e537f87 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -180,7 +180,8 @@ struct ucred {
180#define AF_ALG 38 /* Algorithm sockets */ 180#define AF_ALG 38 /* Algorithm sockets */
181#define AF_NFC 39 /* NFC sockets */ 181#define AF_NFC 39 /* NFC sockets */
182#define AF_VSOCK 40 /* vSockets */ 182#define AF_VSOCK 40 /* vSockets */
183#define AF_MAX 41 /* For now.. */ 183#define AF_RPMSG 41 /* Remote-processor messaging */
184#define AF_MAX 42 /* For now.. */
184 185
185/* Protocol families, same as address families. */ 186/* Protocol families, same as address families. */
186#define PF_UNSPEC AF_UNSPEC 187#define PF_UNSPEC AF_UNSPEC
@@ -225,6 +226,7 @@ struct ucred {
225#define PF_ALG AF_ALG 226#define PF_ALG AF_ALG
226#define PF_NFC AF_NFC 227#define PF_NFC AF_NFC
227#define PF_VSOCK AF_VSOCK 228#define PF_VSOCK AF_VSOCK
229#define PF_RPMSG AF_RPMSG
228#define PF_MAX AF_MAX 230#define PF_MAX AF_MAX
229 231
230/* Maximum queue length specifiable by listen. */ 232/* Maximum queue length specifiable by listen. */
@@ -301,6 +303,7 @@ struct ucred {
301#define SOL_CAIF 278 303#define SOL_CAIF 278
302#define SOL_ALG 279 304#define SOL_ALG 279
303#define SOL_NFC 280 305#define SOL_NFC 280
306#define SOL_RPMSG 281
304 307
305/* IPX options */ 308/* IPX options */
306#define IPX_TYPE 1 309#define IPX_TYPE 1
diff --git a/include/uapi/linux/rpmsg_rpc.h b/include/uapi/linux/rpmsg_rpc.h
new file mode 100644
index 00000000000..2c8724f36cd
--- /dev/null
+++ b/include/uapi/linux/rpmsg_rpc.h
@@ -0,0 +1,208 @@
1/*
2 * Remote Processor Procedure Call Driver
3 *
4 * Copyright(c) 2012-2014 Texas Instruments. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name Texas Instruments nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _UAPI_LINUX_RPMSG_RPC_H_
34#define _UAPI_LINUX_RPMSG_RPC_H_
35
36#include <linux/ioctl.h>
37
38/**
39 * struct rppc_buf_fds - rppc buffer registration/deregistration
40 * @num: number of file descriptors
41 * @fds: pointer to the array holding the file descriptors
42 */
43struct rppc_buf_fds {
44 uint32_t num;
45 int32_t *fds;
46};
47
48/*
49 * ioctl definitions
50 */
51#define RPPC_IOC_MAGIC 'r'
52#define RPPC_IOC_CREATE _IOW(RPPC_IOC_MAGIC, 1, char *)
53#define RPPC_IOC_BUFREGISTER _IOW(RPPC_IOC_MAGIC, 2, struct rppc_buf_fds)
54#define RPPC_IOC_BUFUNREGISTER _IOW(RPPC_IOC_MAGIC, 3, struct rppc_buf_fds)
55#define RPPC_IOC_MAXNR (4)
56
57#define RPPC_MAX_PARAMETERS (10)
58#define RPPC_MAX_TRANSLATIONS (1024)
59#define RPPC_MAX_INST_NAMELEN (48)
60
61/**
62 * enum rppc_param_type - RPC function parameter type
63 * @RPPC_PARAM_TYPE_UNKNOWN: unrecognized parameter
64 * @RPPC_PARAM_TYPE_ATOMIC: an atomic data type, 1 byte to architecture limit
65 * sized bytes
66 * @RPPC_PARAM_TYPE_PTR: a pointer to shared memory. The fd field in the
67 * structures rppc_param and rppc_param_translation must
68 * contain the file descriptor of the associated dma_buf
69 * @RPPC_PARAM_TYPE_STRUCT: (unsupported) a structure type. Will be architecture
70 * width aligned in memory
71 *
72 * These enum values are used to identify the parameter type for every
73 * parameter argument of the remote function.
74 */
75enum rppc_param_type {
76 RPPC_PARAM_TYPE_UNKNOWN = 0,
77 RPPC_PARAM_TYPE_ATOMIC,
78 RPPC_PARAM_TYPE_PTR,
79 RPPC_PARAM_TYPE_STRUCT,
80};
81
82/**
83 * struct rppc_param_translation - pointer translation helper structure
84 * @index: index of the parameter where the translation needs to be done in.
85 * used for computing the primary offset and mapping into kernel
86 * the page from the buffer referred to in the correspoding parameter
87 * @offset: offset from the primary base pointer to the pointer to translate.
88 * This is the secondary offset, and used either for mentioning the
89 * offset from an structure array element base, or within a single
90 * structure which itself is at an offset in an allocated buffer
91 * @base: the base user virtual address of the pointer to translate (used to
92 * calculate translated pointer offset)
93 * @fd: dma_buf file descriptor of the allocated buffer pointer within which
94 * the translated pointer is present
95 */
96struct rppc_param_translation {
97 uint32_t index;
98 ptrdiff_t offset;
99 size_t base;
100 int32_t fd;
101};
102
103/**
104 * struct rppc_param - descriptor structure for each parameter
105 * @type: type of the parameter, as dictated by enum rppc_param_type
106 * @size: size of the data (for atomic types) or size of the containing
107 * structure in which translations are performed
108 * @data: either the parameter value itself (for atomic type) or
109 * the actual user space pointer address to the data (for pointer type)
110 * @base: the base user space pointer address of the original allocated buffer,
111 * providing a reference if data has the pointer that is at an offset
112 * from the original pointer
113 * @fd: file descriptor of the exported allocation (will be used to
114 * import the associated dma_buf within the driver).
115 */
116struct rppc_param {
117 uint32_t type;
118 size_t size;
119 size_t data;
120 size_t base;
121 int32_t fd;
122};
123
124/**
125 * struct rppc_function - descriptor structure for the remote function
126 * @fxn_id: index of the function to invoke on the opened rppc device
127 * @num_params: number of parameters filled in the params field
128 * @params: array of parameter descriptor structures
129 * @num_translations: number of in-place translations to be performed within
130 * the arguments.
131 * @translations: an open array of the translation descriptor structures, whose
132 * length is given in @num_translations. Used for translating
133 * the pointers within the function data.
134 *
135 * This is the primary descriptor structure passed down from the userspace,
136 * describing the function, its parameter arguments and the needed translations.
137 */
138struct rppc_function {
139 uint32_t fxn_id;
140 uint32_t num_params;
141 struct rppc_param params[RPPC_MAX_PARAMETERS];
142 uint32_t num_translations;
143 struct rppc_param_translation translations[0];
144};
145
146/**
147 * struct rppc_function_return - function return status descriptor structure
148 * @fxn_id: index of the function invoked on the opened rppc device
149 * @status: return value of the executed function
150 */
151struct rppc_function_return {
152 uint32_t fxn_id;
153 uint32_t status;
154};
155
156/**
157 * struct rppc_create_instance - rppc channel connector helper
158 * @name: Name of the rppc server device to establish a connection with
159 */
160struct rppc_create_instance {
161 char name[RPPC_MAX_INST_NAMELEN];
162};
163
164/*
165 * helper macros for manipulating the function index in the marshalled packet
166 */
167#define RPPC_DESC_EXEC_SYNC (0x0100)
168#define RPPC_DESC_TYPE_MASK (0x0F00)
169
170/*
171 * helper macros for manipulating the function index in the marshalled packet.
172 * The remote functions are offset by one relative to the client
173 * XXX: Remove the relative offset
174 */
175#define RPPC_SET_FXN_IDX(idx) (((idx) + 1) | 0x80000000)
176#define RPPC_FXN_MASK(idx) (((idx) - 1) & 0x7FFFFFFF)
177
178/**
179 * struct rppc_packet - the actual marshalled packet
180 * @desc: type of function execution, currently only synchronous function
181 * invocations are supported
182 * @msg_id: an incremental message index identifier
183 * @flags: a combination of job id and pool id of the worker threads
184 * of the server
185 * @fxn_id: id of the function to execute
186 * @result: result of the remotely executed function
187 * @data_size: size of the payload packet
188 * @data: variable payload, containing the marshalled function data.
189 *
190 * This is actually a condensed structure of the Remote Command Messaging
191 * (RCM) structure. The initial fields of the structure are used by the
192 * remote-side server to schedule the execution of the function. The actual
193 * variable payload data starts from the .data field. This marshalled packet
194 * is the payload for a rpmsg message.
195 *
196 * XXX: remove or mask unneeded fields, some fields can be stripped down
197 */
198struct rppc_packet {
199 uint16_t desc;
200 uint16_t msg_id;
201 uint32_t flags;
202 uint32_t fxn_id;
203 int32_t result;
204 uint32_t data_size;
205 uint8_t data[0];
206} __packed;
207
208#endif /* _UAPI_LINUX_RPMSG_RPC_H_ */
diff --git a/include/uapi/linux/rpmsg_socket.h b/include/uapi/linux/rpmsg_socket.h
new file mode 100644
index 00000000000..3b26bffacf3
--- /dev/null
+++ b/include/uapi/linux/rpmsg_socket.h
@@ -0,0 +1,47 @@
1/*
2 * Remote processor messaging sockets
3 *
4 * Copyright (C) 2011-2014 Texas Instruments, Inc
5 *
6 * Ohad Ben-Cohen <ohad@wizery.com>
7 * Suman Anna <s-anna@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#ifndef _UAPI_RPMSG_SOCKET_H
20#define _UAPI_RPMSG_SOCKET_H
21
22#include <linux/types.h>
23#include <linux/socket.h>
24
25/* user space needs this */
26#ifndef AF_RPMSG
27#define AF_RPMSG 41
28#define PF_RPMSG AF_RPMSG
29#endif
30
31/* Connection and socket states */
32enum {
33 RPMSG_CONNECTED = 1, /* wait_for_packet() wants this... */
34 RPMSG_OPEN,
35 RPMSG_LISTENING,
36 RPMSG_CLOSED,
37};
38
39struct sockaddr_rpmsg {
40 __kernel_sa_family_t family;
41 __u32 vproc_id;
42 __u32 addr;
43};
44
45#define RPMSG_LOCALHOST ((__u32) ~0UL)
46
47#endif /* _UAPI_RPMSG_SOCKET_H */
diff --git a/net/Makefile b/net/Makefile
index cbbbe6d657c..902436fb3e9 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -72,3 +72,4 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/
72obj-$(CONFIG_VSOCKETS) += vmw_vsock/ 72obj-$(CONFIG_VSOCKETS) += vmw_vsock/
73obj-$(CONFIG_NET_MPLS_GSO) += mpls/ 73obj-$(CONFIG_NET_MPLS_GSO) += mpls/
74obj-$(CONFIG_HSR) += hsr/ 74obj-$(CONFIG_HSR) += hsr/
75obj-$(CONFIG_RPMSG) += rpmsg/
diff --git a/net/rpmsg/Makefile b/net/rpmsg/Makefile
new file mode 100644
index 00000000000..4db19dfdb38
--- /dev/null
+++ b/net/rpmsg/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_RPMSG) += rpmsg_proto.o
diff --git a/net/rpmsg/rpmsg_proto.c b/net/rpmsg/rpmsg_proto.c
new file mode 100644
index 00000000000..4534b6cc954
--- /dev/null
+++ b/net/rpmsg/rpmsg_proto.c
@@ -0,0 +1,684 @@
1/*
2 * AF_RPMSG: Remote processor messaging sockets
3 *
4 * Copyright (C) 2011-2014 Texas Instruments, Inc.
5 *
6 * Ohad Ben-Cohen <ohad@wizery.com>
7 * Robert Tivy <rtivy@ti.com>
8 * G Anthony <a0783926@ti.com>
9 * Suman Anna <s-anna@ti.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#define pr_fmt(fmt) "%s: " fmt, __func__
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/types.h>
27#include <linux/list.h>
28#include <linux/errno.h>
29#include <linux/skbuff.h>
30#include <linux/rwlock.h>
31#include <linux/err.h>
32#include <linux/mutex.h>
33#include <linux/rpmsg.h>
34#include <linux/radix-tree.h>
35#include <linux/remoteproc.h>
36#include <net/sock.h>
37#include <uapi/linux/rpmsg_socket.h>
38
39#define RPMSG_CB(skb) (*(struct sockaddr_rpmsg *)&((skb)->cb))
40
41/* Used to distinguish between bound and connected socket channels in the
42 * radix tree index space.
43 * Must match value as in drivers/rpmsg/virtio_rpmsg_bus.c:
44 */
45#define RPMSG_RESERVED_ADDRESSES (1024)
46
47struct rpmsg_socket {
48 struct sock sk;
49 struct rpmsg_channel *rpdev;
50 bool unregister_rpdev;
51};
52
53/* A two-level radix-tree-based scheme is used to maintain the rpmsg channels
54 * we're exposing to userland. The first radix tree maps vproc index id
55 * to its channels, and the second radix tree associates each channel
56 * with its destination addresses (so sockaddr_rpmsg lookups are quick).
57 *
58 * Currently only channels with a valid dst address are supported (aka 'client'
59 * channels as opposed to 'server' channels which usually only have a valid
60 * src address).
61 */
62static RADIX_TREE(rpmsg_channels, GFP_KERNEL);
63
64/* Synchronization of access to the tree is achieved using a mutex,
65 * because we're using non-atomic radix tree allocations.
66 */
67static DEFINE_MUTEX(rpmsg_channels_lock);
68
69/* A radix tree is used to retrieve the virtproc_info structure
70 * from the associated system-wide unique processor id.
71 */
72static RADIX_TREE(rpmsg_vprocs, GFP_KERNEL);
73static DEFINE_MUTEX(rpmsg_vprocs_lock);
74
75static struct proto rpmsg_proto = {
76 .name = "RPMSG",
77 .owner = THIS_MODULE,
78 .obj_size = sizeof(struct rpmsg_socket),
79};
80
81/* Retrieve the rproc instance so that it can be used for retrieving
82 * the processor id associated with the rpmsg channel.
83 */
84static struct rproc *rpdev_to_rproc(struct rpmsg_channel *rpdev)
85{
86 struct virtio_device *vdev;
87
88 vdev = rpmsg_get_virtio_dev(rpdev);
89 if (!vdev)
90 return NULL;
91
92 return rproc_vdev_to_rproc_safe(vdev);
93}
94
95/* Retrieve the rproc id. The rproc id _relies_ on aliases being defined
96 * in the DT blob for each of the remoteproc devices, and is essentially
97 * the alias id. These are assumed to match to be fixed for a particular
98 * SoC, and this provides a means to have a fixed interface to identify
99 * a remote processor.
100 */
101static int rpmsg_sock_get_proc_id(struct rpmsg_channel *rpdev)
102{
103 struct rproc *rproc = rpdev_to_rproc(rpdev);
104 int id;
105
106 if (!rproc) {
107 WARN_ON(1);
108 return -EINVAL;
109 }
110
111 id = rproc_get_alias_id(rproc);
112 WARN_ON(id < 0);
113
114 return id;
115}
116
117static int rpmsg_sock_connect(struct socket *sock, struct sockaddr *addr,
118 int alen, int flags)
119{
120 struct sock *sk = sock->sk;
121 struct rpmsg_socket *rpsk;
122 struct sockaddr_rpmsg *sa;
123 int err = 0;
124 struct radix_tree_root *vrp_channels;
125 struct rpmsg_channel *rpdev;
126
127 if (sk->sk_state != RPMSG_OPEN)
128 return -EBADFD;
129
130 if (sk->sk_type != SOCK_SEQPACKET)
131 return -EINVAL;
132
133 if (!addr || addr->sa_family != AF_RPMSG)
134 return -EINVAL;
135
136 if (alen < sizeof(*sa))
137 return -EINVAL;
138
139 sa = (struct sockaddr_rpmsg *)addr;
140
141 lock_sock(sk);
142
143 rpsk = container_of(sk, struct rpmsg_socket, sk);
144
145 mutex_lock(&rpmsg_channels_lock);
146
147 /* find the set of channels exposed by this remote processor */
148 vrp_channels = radix_tree_lookup(&rpmsg_channels, sa->vproc_id);
149 if (!vrp_channels) {
150 err = -EINVAL;
151 goto out;
152 }
153
154 /* find the specific channel we need to connect with, by dst addr: */
155 rpdev = radix_tree_lookup(vrp_channels, sa->addr);
156 if (!rpdev) {
157 err = -EINVAL;
158 goto out;
159 }
160
161 rpsk->rpdev = rpdev;
162
163 /* bind this socket with its rpmsg endpoint */
164 rpdev->ept->priv = sk;
165
166 /* XXX take care of disconnection state too */
167 sk->sk_state = RPMSG_CONNECTED;
168
169out:
170 mutex_unlock(&rpmsg_channels_lock);
171 release_sock(sk);
172 return err;
173}
174
175static int rpmsg_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
176 struct msghdr *msg, size_t len)
177{
178 struct sock *sk = sock->sk;
179 struct rpmsg_socket *rpsk;
180 char payload[512];/* todo: sane payload length methodology */
181 int err;
182
183 /* XXX check for sock_error as well ? */
184 /* XXX handle noblock ? */
185 if (msg->msg_flags & MSG_OOB)
186 return -EOPNOTSUPP;
187
188 /* no payload ? */
189 if (msg->msg_iov->iov_base == NULL)
190 return -EINVAL;
191
192 lock_sock(sk);
193
194 /* we don't support loopback at this point */
195 if (sk->sk_state != RPMSG_CONNECTED) {
196 release_sock(sk);
197 return -ENOTCONN;
198 }
199
200 rpsk = container_of(sk, struct rpmsg_socket, sk);
201
202 /* XXX for now, ignore the peer address. later use it
203 * with rpmsg_sendto, but only if user is root
204 */
205 err = memcpy_fromiovec(payload, msg->msg_iov, len);
206 if (err)
207 goto out;
208
209 /* XXX add length validation */
210 err = rpmsg_send(rpsk->rpdev, payload, len);
211 if (err)
212 pr_err("rpmsg_send failed: %d\n", err);
213
214out:
215 release_sock(sk);
216 return err;
217}
218
219static int rpmsg_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
220 struct msghdr *msg, size_t len, int flags)
221{
222 struct sock *sk = sock->sk;
223 struct sockaddr_rpmsg *sa;
224 struct sk_buff *skb;
225 int noblock = flags & MSG_DONTWAIT;
226 int ret;
227
228 if (flags & MSG_OOB) {
229 pr_err("MSG_OOB: %d\n", EOPNOTSUPP);
230 return -EOPNOTSUPP;
231 }
232
233 msg->msg_namelen = 0;
234
235 skb = skb_recv_datagram(sk, flags, noblock, &ret);
236 if (!skb) {
237 /* check for shutdown ? */
238 pr_err("skb_recv_datagram: %d\n", ret);
239 return ret;
240 }
241
242 if (msg->msg_name) {
243 msg->msg_namelen = sizeof(*sa);
244 sa = (struct sockaddr_rpmsg *)msg->msg_name;
245 sa->vproc_id = RPMSG_CB(skb).vproc_id;
246 sa->addr = RPMSG_CB(skb).addr;
247 sa->family = AF_RPMSG;
248 }
249
250 if (len > skb->len) {
251 len = skb->len;
252 } else if (len < skb->len) {
253 pr_warn("user buffer is too small\n");
254 /* XXX truncate or error ? */
255 msg->msg_flags |= MSG_TRUNC;
256 }
257
258 ret = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
259 if (ret) {
260 pr_err("error copying skb data: %d\n", ret);
261 goto out_free;
262 }
263
264 ret = len;
265
266out_free:
267 skb_free_datagram(sk, skb);
268 return ret;
269}
270
271static unsigned int rpmsg_sock_poll(struct file *file, struct socket *sock,
272 poll_table *wait)
273{
274 struct sock *sk = sock->sk;
275 unsigned int mask = 0;
276
277 poll_wait(file, sk_sleep(sk), wait);
278
279 /* exceptional events? */
280 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
281 mask |= POLLERR;
282 if (sk->sk_shutdown & RCV_SHUTDOWN)
283 mask |= POLLRDHUP;
284 if (sk->sk_shutdown == SHUTDOWN_MASK)
285 mask |= POLLHUP;
286
287 /* readable? */
288 if (!skb_queue_empty(&sk->sk_receive_queue) ||
289 (sk->sk_shutdown & RCV_SHUTDOWN))
290 mask |= POLLIN | POLLRDNORM;
291
292 if (sk->sk_state == RPMSG_CLOSED)
293 mask |= POLLHUP;
294
295 /* XXX is writable ?
296 * this depends on the destination processor.
297 * if loopback: we're writable unless no memory
298 * if to remote: we need enabled rpmsg buffer or user supplied bufs
299 * for now, let's always be writable.
300 */
301 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
302
303 return mask;
304}
305
306/* return bound socket address information, either local or remote
307 * note: len is just an output parameter, doesn't carry any input value
308 */
309static int rpmsg_sock_getname(struct socket *sock, struct sockaddr *addr,
310 int *len, int peer)
311{
312 struct sock *sk = sock->sk;
313 struct rpmsg_socket *rpsk;
314 struct rpmsg_channel *rpdev;
315 struct sockaddr_rpmsg *sa;
316
317 rpsk = container_of(sk, struct rpmsg_socket, sk);
318 rpdev = rpsk->rpdev;
319
320 if (!rpdev)
321 return -ENOTCONN;
322
323 addr->sa_family = AF_RPMSG;
324
325 sa = (struct sockaddr_rpmsg *)addr;
326
327 *len = sizeof(*sa);
328
329 if (peer) {
330 sa->vproc_id = rpmsg_sock_get_proc_id(rpdev);
331 sa->addr = rpdev->dst;
332 } else {
333 sa->vproc_id = RPMSG_LOCALHOST;
334 sa->addr = rpsk->rpdev->src;
335 }
336
337 return 0;
338}
339
340static int rpmsg_sock_release(struct socket *sock)
341{
342 struct sock *sk = sock->sk;
343 struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
344 int ret;
345
346 if (!sk)
347 return 0;
348
349 if (rpsk->unregister_rpdev) {
350 ret = rpmsg_destroy_channel(rpsk->rpdev);
351 if (ret)
352 pr_err("rpmsg_destroy_channel failed for sk %p\n", sk);
353 }
354
355 sock_put(sock->sk);
356
357 return 0;
358}
359
360/* Notes:
361 * - calling connect after bind isn't currently supported (is it even needed?).
362 * - userspace arguments to bind aren't intuitive: one needs to provide
363 * the vproc id of the remote processor that the channel needs to be shared
364 * with, and the -local- source address the channel is to be bound with
365 */
366static int
367rpmsg_sock_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
368{
369 struct sock *sk = sock->sk;
370 struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
371 struct rpmsg_channel *rpdev;
372 struct sockaddr_rpmsg *sa = (struct sockaddr_rpmsg *)uaddr;
373 struct virtproc_info *vrp;
374
375 if (sock->state == SS_CONNECTED)
376 return -EINVAL;
377
378 if (addr_len != sizeof(*sa))
379 return -EINVAL;
380
381 if (sa->family != AF_RPMSG)
382 return -EINVAL;
383
384 if (rpsk->rpdev)
385 return -EBUSY;
386
387 if (sk->sk_state != RPMSG_OPEN)
388 return -EINVAL;
389
390 vrp = radix_tree_lookup(&rpmsg_vprocs, sa->vproc_id);
391 if (!vrp)
392 return -EINVAL;
393
394 rpdev = rpmsg_create_channel(vrp, "rpmsg-proto", "", sa->addr,
395 RPMSG_ADDR_ANY);
396 if (!rpdev)
397 return -EINVAL;
398
399 rpsk->rpdev = rpdev;
400 rpsk->unregister_rpdev = true;
401
402 /* bind this socket with its rpmsg endpoint */
403 rpdev->ept->priv = sk;
404
405 sk->sk_state = RPMSG_LISTENING;
406
407 return 0;
408}
409
410static const struct proto_ops rpmsg_sock_ops = {
411 .family = PF_RPMSG,
412 .owner = THIS_MODULE,
413
414 .release = rpmsg_sock_release,
415 .connect = rpmsg_sock_connect,
416 .getname = rpmsg_sock_getname,
417 .sendmsg = rpmsg_sock_sendmsg,
418 .recvmsg = rpmsg_sock_recvmsg,
419 .poll = rpmsg_sock_poll,
420 .bind = rpmsg_sock_bind,
421
422 .listen = sock_no_listen,
423 .accept = sock_no_accept,
424 .ioctl = sock_no_ioctl,
425 .mmap = sock_no_mmap,
426 .socketpair = sock_no_socketpair,
427 .shutdown = sock_no_shutdown,
428 .setsockopt = sock_no_setsockopt,
429 .getsockopt = sock_no_getsockopt
430};
431
432static void rpmsg_sock_destruct(struct sock *sk)
433{
434}
435
436static int rpmsg_sock_create(struct net *net, struct socket *sock, int proto,
437 int kern)
438{
439 struct sock *sk;
440
441 if (sock->type != SOCK_SEQPACKET)
442 return -ESOCKTNOSUPPORT;
443 if (proto != 0)
444 return -EPROTONOSUPPORT;
445
446 sk = sk_alloc(net, PF_RPMSG, GFP_KERNEL, &rpmsg_proto);
447 if (!sk)
448 return -ENOMEM;
449
450 sock->state = SS_UNCONNECTED;
451 sock->ops = &rpmsg_sock_ops;
452 sock_init_data(sock, sk);
453
454 sk->sk_destruct = rpmsg_sock_destruct;
455 sk->sk_protocol = proto;
456
457 sk->sk_state = RPMSG_OPEN;
458
459 return 0;
460}
461
462static const struct net_proto_family rpmsg_proto_family = {
463 .family = PF_RPMSG,
464 .create = rpmsg_sock_create,
465 .owner = THIS_MODULE,
466};
467
468static void __rpmsg_proto_cb(struct device *dev, int from_vproc_id, void *data,
469 int len, struct sock *sk, u32 src)
470{
471 struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
472 struct sk_buff *skb;
473 int ret;
474
475#ifdef RPMSG_PROTO_DEBUG /* left in place only for debugging sake */
476 print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
477 data, len, true);
478#endif
479
480 lock_sock(sk);
481
482 switch (sk->sk_state) {
483 case RPMSG_CONNECTED:
484 if (rpsk->rpdev->dst != src)
485 dev_warn(dev, "unexpected source address: %d\n", src);
486 break;
487 case RPMSG_LISTENING:
488 /* When an inbound message is received while we're listening,
489 * we implicitly become connected
490 */
491 sk->sk_state = RPMSG_CONNECTED;
492 rpsk->rpdev->dst = src;
493 break;
494 default:
495 dev_warn(dev, "unexpected inbound message (from %d)\n", src);
496 break;
497 }
498
499 skb = sock_alloc_send_skb(sk, len, 1, &ret);
500 if (!skb) {
501 dev_err(dev, "sock_alloc_send_skb failed: %d\n", ret);
502 ret = -ENOMEM;
503 goto out;
504 }
505
506 RPMSG_CB(skb).vproc_id = from_vproc_id;
507 RPMSG_CB(skb).addr = src;
508 RPMSG_CB(skb).family = AF_RPMSG;
509
510 memcpy(skb_put(skb, len), data, len);
511
512 ret = sock_queue_rcv_skb(sk, skb);
513 if (ret) {
514 dev_err(dev, "sock_queue_rcv_skb failed: %d\n", ret);
515 kfree_skb(skb);
516 }
517
518out:
519 release_sock(sk);
520}
521
522static void rpmsg_proto_cb(struct rpmsg_channel *rpdev, void *data, int len,
523 void *priv, u32 src)
524{
525 int id = rpmsg_sock_get_proc_id(rpdev);
526
527 __rpmsg_proto_cb(&rpdev->dev, id, data, len, priv, src);
528}
529
530/* every channel we're probed with is exposed to userland via the Socket API */
531static int rpmsg_proto_probe(struct rpmsg_channel *rpdev)
532{
533 struct device *dev = &rpdev->dev;
534 int ret, dst = rpdev->dst, id;
535 struct radix_tree_root *vrp_channels;
536 struct virtproc_info *vrp;
537
538 id = rpmsg_sock_get_proc_id(rpdev);
539
540 vrp = radix_tree_lookup(&rpmsg_vprocs, id);
541 if (vrp && vrp != rpdev->vrp)
542 dev_err(dev, "id %d already associated to different vrp\n",
543 id);
544
545 if (dst == RPMSG_ADDR_ANY)
546 return 0;
547
548 /* associate id/vrp for later lookup in rpmsg_sock_bind() */
549 if (!vrp) {
550 mutex_lock(&rpmsg_vprocs_lock);
551 ret = radix_tree_insert(&rpmsg_vprocs, (unsigned long)id,
552 rpdev->vrp);
553 mutex_unlock(&rpmsg_vprocs_lock);
554 if (ret) {
555 dev_err(dev, "radix_tree_insert(%d) failed: %d\n",
556 id, ret);
557 return ret;
558 }
559 }
560
561 mutex_lock(&rpmsg_channels_lock);
562
563 /* are we exposing channels for this remote processor yet ? */
564 vrp_channels = radix_tree_lookup(&rpmsg_channels, id);
565 /* not yet ? let's prepare the 2nd radix tree level then */
566 if (!vrp_channels) {
567 vrp_channels = kzalloc(sizeof(*vrp_channels), GFP_KERNEL);
568 INIT_RADIX_TREE(vrp_channels, GFP_KERNEL);
569 /* now let's associate the new channel with its vrp */
570 ret = radix_tree_insert(&rpmsg_channels, id, vrp_channels);
571 if (ret) {
572 dev_err(dev, "radix_tree_insert failed: %d\n", ret);
573 kfree(vrp_channels);
574 goto out;
575 }
576 }
577
578 /* let's associate the new channel with its dst */
579 ret = radix_tree_insert(vrp_channels, dst, rpdev);
580 if (ret)
581 dev_err(dev, "failed to add rpmsg addr %d: %d\n", dst, ret);
582
583out:
584 mutex_unlock(&rpmsg_channels_lock);
585
586 return ret;
587}
588
589static void rpmsg_proto_remove(struct rpmsg_channel *rpdev)
590{
591 struct device *dev = &rpdev->dev;
592 int id, dst = rpdev->dst, src = rpdev->src;
593 struct radix_tree_root *vrp_channels;
594
595 if (dst == RPMSG_ADDR_ANY)
596 return;
597
598 id = rpmsg_sock_get_proc_id(rpdev);
599
600 mutex_lock(&rpmsg_channels_lock);
601
602 vrp_channels = radix_tree_lookup(&rpmsg_channels, id);
603 if (!vrp_channels) {
604 dev_err(dev, "can't find channels for this vrp: %d\n", id);
605 goto out;
606 }
607
608 /* Only remove non-reserved channels from the tree, as only these
609 * were "probed". Note: bind is not causing a probe, and bound
610 * sockets have src addresses < RPMSG_RESERVED_ADDRESSES.
611 */
612 if (src >= RPMSG_RESERVED_ADDRESSES) {
613 mutex_lock(&rpmsg_vprocs_lock);
614 if (!radix_tree_delete(&rpmsg_vprocs, id))
615 dev_err(dev, "failed to delete id %d\n", id);
616 mutex_unlock(&rpmsg_vprocs_lock);
617
618 if (!radix_tree_delete(vrp_channels, dst))
619 dev_err(dev, "failed to delete rpmsg %d\n", dst);
620 }
621
622out:
623 mutex_unlock(&rpmsg_channels_lock);
624}
625
626static struct rpmsg_device_id rpmsg_proto_id_table[] = {
627 { .name = "rpmsg-proto" },
628 { },
629};
630MODULE_DEVICE_TABLE(rpmsg, rpmsg_proto_id_table);
631
632static struct rpmsg_driver rpmsg_proto_driver = {
633 .drv.name = KBUILD_MODNAME,
634 .drv.owner = THIS_MODULE,
635 .id_table = rpmsg_proto_id_table,
636 .probe = rpmsg_proto_probe,
637 .callback = rpmsg_proto_cb,
638 .remove = rpmsg_proto_remove,
639};
640
641static int __init rpmsg_proto_init(void)
642{
643 int ret;
644
645 ret = proto_register(&rpmsg_proto, 0);
646 if (ret) {
647 pr_err("proto_register failed: %d\n", ret);
648 return ret;
649 }
650
651 ret = sock_register(&rpmsg_proto_family);
652 if (ret) {
653 pr_err("sock_register failed: %d\n", ret);
654 goto proto_unreg;
655 }
656
657 ret = register_rpmsg_driver(&rpmsg_proto_driver);
658 if (ret) {
659 pr_err("register_rpmsg_driver failed: %d\n", ret);
660 goto sock_unreg;
661 }
662
663 return 0;
664
665sock_unreg:
666 sock_unregister(PF_RPMSG);
667proto_unreg:
668 proto_unregister(&rpmsg_proto);
669 return ret;
670}
671
672static void __exit rpmsg_proto_exit(void)
673{
674 unregister_rpmsg_driver(&rpmsg_proto_driver);
675 sock_unregister(PF_RPMSG);
676 proto_unregister(&rpmsg_proto);
677}
678
679module_init(rpmsg_proto_init);
680module_exit(rpmsg_proto_exit);
681
682MODULE_DESCRIPTION("Remote processor messaging protocol");
683MODULE_LICENSE("GPL v2");
684MODULE_ALIAS_NETPROTO(AF_RPMSG);