1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2022, STMicroelectronics |
4 | * Copyright (c) 2016, Linaro Ltd. |
5 | * Copyright (c) 2012, Michal Simek <monstr@monstr.eu> |
6 | * Copyright (c) 2012, PetaLogix |
7 | * Copyright (c) 2011, Texas Instruments, Inc. |
8 | * Copyright (c) 2011, Google, Inc. |
9 | * |
10 | * Based on rpmsg performance statistics driver by Michal Simek, which in turn |
11 | * was based on TI & Google OMX rpmsg driver. |
12 | */ |
13 | |
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | |
16 | #include <linux/cdev.h> |
17 | #include <linux/device.h> |
18 | #include <linux/fs.h> |
19 | #include <linux/idr.h> |
20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> |
22 | #include <linux/poll.h> |
23 | #include <linux/rpmsg.h> |
24 | #include <linux/skbuff.h> |
25 | #include <linux/slab.h> |
26 | #include <linux/uaccess.h> |
27 | #include <uapi/linux/rpmsg.h> |
28 | |
29 | #include "rpmsg_char.h" |
30 | #include "rpmsg_internal.h" |
31 | |
32 | #define RPMSG_DEV_MAX (MINORMASK + 1) |
33 | |
34 | static dev_t rpmsg_major; |
35 | |
36 | static DEFINE_IDA(rpmsg_ept_ida); |
37 | static DEFINE_IDA(rpmsg_minor_ida); |
38 | |
39 | #define dev_to_eptdev(dev) container_of(dev, struct rpmsg_eptdev, dev) |
40 | #define cdev_to_eptdev(i_cdev) container_of(i_cdev, struct rpmsg_eptdev, cdev) |
41 | |
42 | /** |
43 | * struct rpmsg_eptdev - endpoint device context |
44 | * @dev: endpoint device |
45 | * @cdev: cdev for the endpoint device |
46 | * @rpdev: underlaying rpmsg device |
47 | * @chinfo: info used to open the endpoint |
48 | * @ept_lock: synchronization of @ept modifications |
49 | * @ept: rpmsg endpoint reference, when open |
50 | * @queue_lock: synchronization of @queue operations |
51 | * @queue: incoming message queue |
52 | * @readq: wait object for incoming queue |
53 | * @default_ept: set to channel default endpoint if the default endpoint should be re-used |
54 | * on device open to prevent endpoint address update. |
55 | * remote_flow_restricted: to indicate if the remote has requested for flow to be limited |
56 | * remote_flow_updated: to indicate if the flow control has been requested |
57 | */ |
58 | struct rpmsg_eptdev { |
59 | struct device dev; |
60 | struct cdev cdev; |
61 | |
62 | struct rpmsg_device *rpdev; |
63 | struct rpmsg_channel_info chinfo; |
64 | |
65 | struct mutex ept_lock; |
66 | struct rpmsg_endpoint *ept; |
67 | struct rpmsg_endpoint *default_ept; |
68 | |
69 | spinlock_t queue_lock; |
70 | struct sk_buff_head queue; |
71 | wait_queue_head_t readq; |
72 | |
73 | bool remote_flow_restricted; |
74 | bool remote_flow_updated; |
75 | }; |
76 | |
77 | int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data) |
78 | { |
79 | struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev); |
80 | |
81 | mutex_lock(&eptdev->ept_lock); |
82 | eptdev->rpdev = NULL; |
83 | if (eptdev->ept) { |
84 | /* The default endpoint is released by the rpmsg core */ |
85 | if (!eptdev->default_ept) |
86 | rpmsg_destroy_ept(eptdev->ept); |
87 | eptdev->ept = NULL; |
88 | } |
89 | mutex_unlock(lock: &eptdev->ept_lock); |
90 | |
91 | /* wake up any blocked readers */ |
92 | wake_up_interruptible(&eptdev->readq); |
93 | |
94 | cdev_device_del(cdev: &eptdev->cdev, dev: &eptdev->dev); |
95 | put_device(dev: &eptdev->dev); |
96 | |
97 | return 0; |
98 | } |
99 | EXPORT_SYMBOL(rpmsg_chrdev_eptdev_destroy); |
100 | |
101 | static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len, |
102 | void *priv, u32 addr) |
103 | { |
104 | struct rpmsg_eptdev *eptdev = priv; |
105 | struct sk_buff *skb; |
106 | |
107 | skb = alloc_skb(size: len, GFP_ATOMIC); |
108 | if (!skb) |
109 | return -ENOMEM; |
110 | |
111 | skb_put_data(skb, data: buf, len); |
112 | |
113 | spin_lock(lock: &eptdev->queue_lock); |
114 | skb_queue_tail(list: &eptdev->queue, newsk: skb); |
115 | spin_unlock(lock: &eptdev->queue_lock); |
116 | |
117 | /* wake up any blocking processes, waiting for new data */ |
118 | wake_up_interruptible(&eptdev->readq); |
119 | |
120 | return 0; |
121 | } |
122 | |
123 | static int rpmsg_ept_flow_cb(struct rpmsg_device *rpdev, void *priv, bool enable) |
124 | { |
125 | struct rpmsg_eptdev *eptdev = priv; |
126 | |
127 | eptdev->remote_flow_restricted = enable; |
128 | eptdev->remote_flow_updated = true; |
129 | |
130 | wake_up_interruptible(&eptdev->readq); |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) |
136 | { |
137 | struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); |
138 | struct rpmsg_endpoint *ept; |
139 | struct rpmsg_device *rpdev = eptdev->rpdev; |
140 | struct device *dev = &eptdev->dev; |
141 | |
142 | mutex_lock(&eptdev->ept_lock); |
143 | if (eptdev->ept) { |
144 | mutex_unlock(lock: &eptdev->ept_lock); |
145 | return -EBUSY; |
146 | } |
147 | |
148 | if (!eptdev->rpdev) { |
149 | mutex_unlock(lock: &eptdev->ept_lock); |
150 | return -ENETRESET; |
151 | } |
152 | |
153 | get_device(dev); |
154 | |
155 | /* |
156 | * If the default_ept is set, the rpmsg device default endpoint is used. |
157 | * Else a new endpoint is created on open that will be destroyed on release. |
158 | */ |
159 | if (eptdev->default_ept) |
160 | ept = eptdev->default_ept; |
161 | else |
162 | ept = rpmsg_create_ept(rpdev, cb: rpmsg_ept_cb, priv: eptdev, chinfo: eptdev->chinfo); |
163 | |
164 | if (!ept) { |
165 | dev_err(dev, "failed to open %s\n" , eptdev->chinfo.name); |
166 | put_device(dev); |
167 | mutex_unlock(lock: &eptdev->ept_lock); |
168 | return -EINVAL; |
169 | } |
170 | |
171 | ept->flow_cb = rpmsg_ept_flow_cb; |
172 | eptdev->ept = ept; |
173 | filp->private_data = eptdev; |
174 | mutex_unlock(lock: &eptdev->ept_lock); |
175 | |
176 | return 0; |
177 | } |
178 | |
179 | static int rpmsg_eptdev_release(struct inode *inode, struct file *filp) |
180 | { |
181 | struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); |
182 | struct device *dev = &eptdev->dev; |
183 | |
184 | /* Close the endpoint, if it's not already destroyed by the parent */ |
185 | mutex_lock(&eptdev->ept_lock); |
186 | if (eptdev->ept) { |
187 | if (!eptdev->default_ept) |
188 | rpmsg_destroy_ept(eptdev->ept); |
189 | eptdev->ept = NULL; |
190 | } |
191 | mutex_unlock(lock: &eptdev->ept_lock); |
192 | eptdev->remote_flow_updated = false; |
193 | |
194 | /* Discard all SKBs */ |
195 | skb_queue_purge(list: &eptdev->queue); |
196 | |
197 | put_device(dev); |
198 | |
199 | return 0; |
200 | } |
201 | |
202 | static ssize_t rpmsg_eptdev_read_iter(struct kiocb *iocb, struct iov_iter *to) |
203 | { |
204 | struct file *filp = iocb->ki_filp; |
205 | struct rpmsg_eptdev *eptdev = filp->private_data; |
206 | unsigned long flags; |
207 | struct sk_buff *skb; |
208 | int use; |
209 | |
210 | if (!eptdev->ept) |
211 | return -EPIPE; |
212 | |
213 | spin_lock_irqsave(&eptdev->queue_lock, flags); |
214 | |
215 | /* Wait for data in the queue */ |
216 | if (skb_queue_empty(list: &eptdev->queue)) { |
217 | spin_unlock_irqrestore(lock: &eptdev->queue_lock, flags); |
218 | |
219 | if (filp->f_flags & O_NONBLOCK) |
220 | return -EAGAIN; |
221 | |
222 | /* Wait until we get data or the endpoint goes away */ |
223 | if (wait_event_interruptible(eptdev->readq, |
224 | !skb_queue_empty(&eptdev->queue) || |
225 | !eptdev->ept)) |
226 | return -ERESTARTSYS; |
227 | |
228 | /* We lost the endpoint while waiting */ |
229 | if (!eptdev->ept) |
230 | return -EPIPE; |
231 | |
232 | spin_lock_irqsave(&eptdev->queue_lock, flags); |
233 | } |
234 | |
235 | skb = skb_dequeue(list: &eptdev->queue); |
236 | spin_unlock_irqrestore(lock: &eptdev->queue_lock, flags); |
237 | if (!skb) |
238 | return -EFAULT; |
239 | |
240 | use = min_t(size_t, iov_iter_count(to), skb->len); |
241 | if (copy_to_iter(addr: skb->data, bytes: use, i: to) != use) |
242 | use = -EFAULT; |
243 | |
244 | kfree_skb(skb); |
245 | |
246 | return use; |
247 | } |
248 | |
249 | static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb, |
250 | struct iov_iter *from) |
251 | { |
252 | struct file *filp = iocb->ki_filp; |
253 | struct rpmsg_eptdev *eptdev = filp->private_data; |
254 | size_t len = iov_iter_count(i: from); |
255 | void *kbuf; |
256 | int ret; |
257 | |
258 | kbuf = kzalloc(size: len, GFP_KERNEL); |
259 | if (!kbuf) |
260 | return -ENOMEM; |
261 | |
262 | if (!copy_from_iter_full(addr: kbuf, bytes: len, i: from)) { |
263 | ret = -EFAULT; |
264 | goto free_kbuf; |
265 | } |
266 | |
267 | if (mutex_lock_interruptible(&eptdev->ept_lock)) { |
268 | ret = -ERESTARTSYS; |
269 | goto free_kbuf; |
270 | } |
271 | |
272 | if (!eptdev->ept) { |
273 | ret = -EPIPE; |
274 | goto unlock_eptdev; |
275 | } |
276 | |
277 | if (filp->f_flags & O_NONBLOCK) { |
278 | ret = rpmsg_trysendto(ept: eptdev->ept, data: kbuf, len, dst: eptdev->chinfo.dst); |
279 | if (ret == -ENOMEM) |
280 | ret = -EAGAIN; |
281 | } else { |
282 | ret = rpmsg_sendto(ept: eptdev->ept, data: kbuf, len, dst: eptdev->chinfo.dst); |
283 | } |
284 | |
285 | unlock_eptdev: |
286 | mutex_unlock(lock: &eptdev->ept_lock); |
287 | |
288 | free_kbuf: |
289 | kfree(objp: kbuf); |
290 | return ret < 0 ? ret : len; |
291 | } |
292 | |
293 | static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait) |
294 | { |
295 | struct rpmsg_eptdev *eptdev = filp->private_data; |
296 | __poll_t mask = 0; |
297 | |
298 | if (!eptdev->ept) |
299 | return EPOLLERR; |
300 | |
301 | poll_wait(filp, wait_address: &eptdev->readq, p: wait); |
302 | |
303 | if (!skb_queue_empty(list: &eptdev->queue)) |
304 | mask |= EPOLLIN | EPOLLRDNORM; |
305 | |
306 | if (eptdev->remote_flow_updated) |
307 | mask |= EPOLLPRI; |
308 | |
309 | mutex_lock(&eptdev->ept_lock); |
310 | mask |= rpmsg_poll(ept: eptdev->ept, filp, wait); |
311 | mutex_unlock(lock: &eptdev->ept_lock); |
312 | |
313 | return mask; |
314 | } |
315 | |
316 | static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd, |
317 | unsigned long arg) |
318 | { |
319 | struct rpmsg_eptdev *eptdev = fp->private_data; |
320 | |
321 | bool set; |
322 | int ret; |
323 | |
324 | switch (cmd) { |
325 | case RPMSG_GET_OUTGOING_FLOWCONTROL: |
326 | eptdev->remote_flow_updated = false; |
327 | ret = put_user(eptdev->remote_flow_restricted, (int __user *)arg); |
328 | break; |
329 | case RPMSG_SET_INCOMING_FLOWCONTROL: |
330 | if (arg > 1) { |
331 | ret = -EINVAL; |
332 | break; |
333 | } |
334 | set = !!arg; |
335 | ret = rpmsg_set_flow_control(ept: eptdev->ept, pause: set, dst: eptdev->chinfo.dst); |
336 | break; |
337 | case RPMSG_DESTROY_EPT_IOCTL: |
338 | /* Don't allow to destroy a default endpoint. */ |
339 | if (eptdev->default_ept) { |
340 | ret = -EINVAL; |
341 | break; |
342 | } |
343 | ret = rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL); |
344 | break; |
345 | default: |
346 | ret = -EINVAL; |
347 | } |
348 | |
349 | return ret; |
350 | } |
351 | |
352 | static const struct file_operations rpmsg_eptdev_fops = { |
353 | .owner = THIS_MODULE, |
354 | .open = rpmsg_eptdev_open, |
355 | .release = rpmsg_eptdev_release, |
356 | .read_iter = rpmsg_eptdev_read_iter, |
357 | .write_iter = rpmsg_eptdev_write_iter, |
358 | .poll = rpmsg_eptdev_poll, |
359 | .unlocked_ioctl = rpmsg_eptdev_ioctl, |
360 | .compat_ioctl = compat_ptr_ioctl, |
361 | }; |
362 | |
363 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, |
364 | char *buf) |
365 | { |
366 | struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev); |
367 | |
368 | return sprintf(buf, fmt: "%s\n" , eptdev->chinfo.name); |
369 | } |
370 | static DEVICE_ATTR_RO(name); |
371 | |
372 | static ssize_t src_show(struct device *dev, struct device_attribute *attr, |
373 | char *buf) |
374 | { |
375 | struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev); |
376 | |
377 | return sprintf(buf, fmt: "%d\n" , eptdev->chinfo.src); |
378 | } |
379 | static DEVICE_ATTR_RO(src); |
380 | |
381 | static ssize_t dst_show(struct device *dev, struct device_attribute *attr, |
382 | char *buf) |
383 | { |
384 | struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev); |
385 | |
386 | return sprintf(buf, fmt: "%d\n" , eptdev->chinfo.dst); |
387 | } |
388 | static DEVICE_ATTR_RO(dst); |
389 | |
390 | static struct attribute *rpmsg_eptdev_attrs[] = { |
391 | &dev_attr_name.attr, |
392 | &dev_attr_src.attr, |
393 | &dev_attr_dst.attr, |
394 | NULL |
395 | }; |
396 | ATTRIBUTE_GROUPS(rpmsg_eptdev); |
397 | |
398 | static void rpmsg_eptdev_release_device(struct device *dev) |
399 | { |
400 | struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev); |
401 | |
402 | ida_simple_remove(&rpmsg_ept_ida, dev->id); |
403 | ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); |
404 | kfree(objp: eptdev); |
405 | } |
406 | |
407 | static struct rpmsg_eptdev *rpmsg_chrdev_eptdev_alloc(struct rpmsg_device *rpdev, |
408 | struct device *parent) |
409 | { |
410 | struct rpmsg_eptdev *eptdev; |
411 | struct device *dev; |
412 | |
413 | eptdev = kzalloc(size: sizeof(*eptdev), GFP_KERNEL); |
414 | if (!eptdev) |
415 | return ERR_PTR(error: -ENOMEM); |
416 | |
417 | dev = &eptdev->dev; |
418 | eptdev->rpdev = rpdev; |
419 | |
420 | mutex_init(&eptdev->ept_lock); |
421 | spin_lock_init(&eptdev->queue_lock); |
422 | skb_queue_head_init(list: &eptdev->queue); |
423 | init_waitqueue_head(&eptdev->readq); |
424 | |
425 | device_initialize(dev); |
426 | dev->class = rpmsg_class; |
427 | dev->parent = parent; |
428 | dev->groups = rpmsg_eptdev_groups; |
429 | dev_set_drvdata(dev, data: eptdev); |
430 | |
431 | cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); |
432 | eptdev->cdev.owner = THIS_MODULE; |
433 | |
434 | return eptdev; |
435 | } |
436 | |
437 | static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev *eptdev, struct rpmsg_channel_info chinfo) |
438 | { |
439 | struct device *dev = &eptdev->dev; |
440 | int ret; |
441 | |
442 | eptdev->chinfo = chinfo; |
443 | |
444 | ret = ida_simple_get(&rpmsg_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL); |
445 | if (ret < 0) |
446 | goto free_eptdev; |
447 | dev->devt = MKDEV(MAJOR(rpmsg_major), ret); |
448 | |
449 | ret = ida_simple_get(&rpmsg_ept_ida, 0, 0, GFP_KERNEL); |
450 | if (ret < 0) |
451 | goto free_minor_ida; |
452 | dev->id = ret; |
453 | dev_set_name(dev, name: "rpmsg%d" , ret); |
454 | |
455 | ret = cdev_device_add(cdev: &eptdev->cdev, dev: &eptdev->dev); |
456 | if (ret) |
457 | goto free_ept_ida; |
458 | |
459 | /* We can now rely on the release function for cleanup */ |
460 | dev->release = rpmsg_eptdev_release_device; |
461 | |
462 | return ret; |
463 | |
464 | free_ept_ida: |
465 | ida_simple_remove(&rpmsg_ept_ida, dev->id); |
466 | free_minor_ida: |
467 | ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); |
468 | free_eptdev: |
469 | put_device(dev); |
470 | kfree(objp: eptdev); |
471 | |
472 | return ret; |
473 | } |
474 | |
475 | int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *parent, |
476 | struct rpmsg_channel_info chinfo) |
477 | { |
478 | struct rpmsg_eptdev *eptdev; |
479 | |
480 | eptdev = rpmsg_chrdev_eptdev_alloc(rpdev, parent); |
481 | if (IS_ERR(ptr: eptdev)) |
482 | return PTR_ERR(ptr: eptdev); |
483 | |
484 | return rpmsg_chrdev_eptdev_add(eptdev, chinfo); |
485 | } |
486 | EXPORT_SYMBOL(rpmsg_chrdev_eptdev_create); |
487 | |
488 | static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev) |
489 | { |
490 | struct rpmsg_channel_info chinfo; |
491 | struct rpmsg_eptdev *eptdev; |
492 | struct device *dev = &rpdev->dev; |
493 | |
494 | memcpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); |
495 | chinfo.src = rpdev->src; |
496 | chinfo.dst = rpdev->dst; |
497 | |
498 | eptdev = rpmsg_chrdev_eptdev_alloc(rpdev, parent: dev); |
499 | if (IS_ERR(ptr: eptdev)) |
500 | return PTR_ERR(ptr: eptdev); |
501 | |
502 | /* Set the default_ept to the rpmsg device endpoint */ |
503 | eptdev->default_ept = rpdev->ept; |
504 | |
505 | /* |
506 | * The rpmsg_ept_cb uses *priv parameter to get its rpmsg_eptdev context. |
507 | * Storedit in default_ept *priv field. |
508 | */ |
509 | eptdev->default_ept->priv = eptdev; |
510 | |
511 | return rpmsg_chrdev_eptdev_add(eptdev, chinfo); |
512 | } |
513 | |
514 | static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev) |
515 | { |
516 | int ret; |
517 | |
518 | ret = device_for_each_child(dev: &rpdev->dev, NULL, fn: rpmsg_chrdev_eptdev_destroy); |
519 | if (ret) |
520 | dev_warn(&rpdev->dev, "failed to destroy endpoints: %d\n" , ret); |
521 | } |
522 | |
523 | static struct rpmsg_device_id rpmsg_chrdev_id_table[] = { |
524 | { .name = "rpmsg-raw" }, |
525 | { }, |
526 | }; |
527 | |
528 | static struct rpmsg_driver rpmsg_chrdev_driver = { |
529 | .probe = rpmsg_chrdev_probe, |
530 | .remove = rpmsg_chrdev_remove, |
531 | .callback = rpmsg_ept_cb, |
532 | .id_table = rpmsg_chrdev_id_table, |
533 | .drv.name = "rpmsg_chrdev" , |
534 | }; |
535 | |
536 | static int rpmsg_chrdev_init(void) |
537 | { |
538 | int ret; |
539 | |
540 | ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg_char" ); |
541 | if (ret < 0) { |
542 | pr_err("failed to allocate char dev region\n" ); |
543 | return ret; |
544 | } |
545 | |
546 | ret = register_rpmsg_driver(&rpmsg_chrdev_driver); |
547 | if (ret < 0) { |
548 | pr_err("rpmsg: failed to register rpmsg raw driver\n" ); |
549 | goto free_region; |
550 | } |
551 | |
552 | return 0; |
553 | |
554 | free_region: |
555 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
556 | |
557 | return ret; |
558 | } |
559 | postcore_initcall(rpmsg_chrdev_init); |
560 | |
561 | static void rpmsg_chrdev_exit(void) |
562 | { |
563 | unregister_rpmsg_driver(drv: &rpmsg_chrdev_driver); |
564 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
565 | } |
566 | module_exit(rpmsg_chrdev_exit); |
567 | |
568 | MODULE_ALIAS("rpmsg:rpmsg_chrdev" ); |
569 | MODULE_LICENSE("GPL v2" ); |
570 | |