From a138c883193a66c3aaee554c8f976f62469c66a7 Mon Sep 17 00:00:00 2001 From: "Anna, Suman" Date: Fri, 12 Aug 2016 18:42:28 -0500 Subject: samples/rpmsg: add support for multiple instances The current rpmsg_client_sample is a very simple example and is not designed to handle multiple instances. Add support for multiple instances, so that the same number of pings are sent to each instance. The instances can be on one or multiple remote processors. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- samples/rpmsg/rpmsg_client_sample.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'samples') diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c index d0e249c90668..7e17d1c0aaf2 100644 --- a/samples/rpmsg/rpmsg_client_sample.c +++ b/samples/rpmsg/rpmsg_client_sample.c @@ -24,19 +24,24 @@ #define MSG "hello world!" #define MSG_LIMIT 100 +struct instance_data { + int rx_count; +}; + static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, void *priv, u32 src) { int ret; - static int rx_count; + struct instance_data *idata = dev_get_drvdata(&rpdev->dev); - dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src); + dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", + ++idata->rx_count, src); print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, data, len, true); /* samples should not live forever */ - if (rx_count >= MSG_LIMIT) { + if (idata->rx_count >= MSG_LIMIT) { dev_info(&rpdev->dev, "goodbye!\n"); return; } @@ -50,10 +55,17 @@ static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) { int ret; + struct instance_data *idata; dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", rpdev->src, rpdev->dst); + idata = devm_kzalloc(&rpdev->dev, sizeof(*idata), GFP_KERNEL); + if (!idata) + return -ENOMEM; + + dev_set_drvdata(&rpdev->dev, idata); + /* send a message to our remote processor */ ret = rpmsg_send(rpdev, MSG, strlen(MSG)); if (ret) { -- cgit v1.2.3-59-g8ed1b From 2a48d7322dc88f1bc6c8bd9e087fc6341ba659fd Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 1 Sep 2016 15:27:55 -0700 Subject: rpmsg: rpmsg_send() operations takes rpmsg_endpoint The rpmsg_send() operations has been taking a rpmsg_device, but this forces users of secondary rpmsg_endpoints to use the rpmsg_sendto() interface - by extracting source and destination from the given data structures. If we instead pass the rpmsg_endpoint to these functions a service can use rpmsg_sendto() to respond to messages, even on secondary endpoints. In addition this would allow us to support operations on multiple channels in future backends that does not support off-channel operations. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/virtio_rpmsg_bus.c | 6 ++-- include/linux/rpmsg.h | 70 +++++++++++++++++++++---------------- samples/rpmsg/rpmsg_client_sample.c | 4 +-- 3 files changed, 45 insertions(+), 35 deletions(-) (limited to 'samples') diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index c4bd89ea7681..345036b485d7 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -379,10 +379,10 @@ static int rpmsg_dev_probe(struct device *dev) struct rpmsg_ns_msg nsm; strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); - nsm.addr = rpdev->src; + nsm.addr = rpdev->ept->addr; nsm.flags = RPMSG_NS_CREATE; - err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); + err = rpmsg_sendto(rpdev->ept, &nsm, sizeof(nsm), RPMSG_NS_ADDR); if (err) dev_err(dev, "failed to announce service %d\n", err); } @@ -407,7 +407,7 @@ static int rpmsg_dev_remove(struct device *dev) nsm.addr = rpdev->src; nsm.flags = RPMSG_NS_DESTROY; - err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); + err = rpmsg_sendto(rpdev->ept, &nsm, sizeof(nsm), RPMSG_NS_ADDR); if (err) dev_err(dev, "failed to announce service %d\n", err); } diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 2b97c711a5e3..a901a331a190 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -193,13 +193,14 @@ rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); /** * rpmsg_send() - send a message across to the remote processor - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @data: payload of message * @len: length of payload * - * This function sends @data of length @len on the @rpdev channel. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to, using @rpdev's source and destination addresses. + * This function sends @data of length @len on the @ept endpoint. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to, using @ept's address and its associated rpmsg + * device destination addresses. * In case there are no TX buffers available, the function will block until * one becomes available, or a timeout of 15 seconds elapses. When the latter * happens, -ERESTARTSYS is returned. @@ -208,23 +209,24 @@ rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); * * Returns 0 on success and an appropriate error value on failure. */ -static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) +static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) { - u32 src = rpdev->src, dst = rpdev->dst; + struct rpmsg_channel *rpdev = ept->rpdev; + u32 src = ept->addr, dst = rpdev->dst; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); } /** * rpmsg_sendto() - send a message across to the remote processor, specify dst - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @data: payload of message * @len: length of payload * @dst: destination address * * This function sends @data of length @len to the remote @dst address. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to, using @rpdev's source address. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to, using @ept's address as source. * In case there are no TX buffers available, the function will block until * one becomes available, or a timeout of 15 seconds elapses. When the latter * happens, -ERESTARTSYS is returned. @@ -234,16 +236,17 @@ static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) * Returns 0 on success and an appropriate error value on failure. */ static inline -int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) +int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { - u32 src = rpdev->src; + struct rpmsg_channel *rpdev = ept->rpdev; + u32 src = ept->addr; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); } /** * rpmsg_send_offchannel() - send a message using explicit src/dst addresses - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @src: source address * @dst: destination address * @data: payload of message @@ -251,8 +254,8 @@ int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) * * This function sends @data of length @len to the remote @dst address, * and uses @src as the source address. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to. * In case there are no TX buffers available, the function will block until * one becomes available, or a timeout of 15 seconds elapses. When the latter * happens, -ERESTARTSYS is returned. @@ -262,21 +265,24 @@ int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) * Returns 0 on success and an appropriate error value on failure. */ static inline -int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, +int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { + struct rpmsg_channel *rpdev = ept->rpdev; + return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); } /** * rpmsg_send() - send a message across to the remote processor - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @data: payload of message * @len: length of payload * - * This function sends @data of length @len on the @rpdev channel. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to, using @rpdev's source and destination addresses. + * This function sends @data of length @len on the @ept endpoint. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to, using @ept's address as source and its associated + * rpdev's address as destination. * In case there are no TX buffers available, the function will immediately * return -ENOMEM without waiting until one becomes available. * @@ -285,23 +291,24 @@ int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, * Returns 0 on success and an appropriate error value on failure. */ static inline -int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) +int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) { - u32 src = rpdev->src, dst = rpdev->dst; + struct rpmsg_channel *rpdev = ept->rpdev; + u32 src = ept->addr, dst = rpdev->dst; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); } /** * rpmsg_sendto() - send a message across to the remote processor, specify dst - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @data: payload of message * @len: length of payload * @dst: destination address * * This function sends @data of length @len to the remote @dst address. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to, using @rpdev's source address. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to, using @ept's address as source. * In case there are no TX buffers available, the function will immediately * return -ENOMEM without waiting until one becomes available. * @@ -310,16 +317,17 @@ int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) * Returns 0 on success and an appropriate error value on failure. */ static inline -int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) +int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { - u32 src = rpdev->src; + struct rpmsg_channel *rpdev = ept->rpdev; + u32 src = ept->addr; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); } /** * rpmsg_send_offchannel() - send a message using explicit src/dst addresses - * @rpdev: the rpmsg channel + * @ept: the rpmsg endpoint * @src: source address * @dst: destination address * @data: payload of message @@ -327,8 +335,8 @@ int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) * * This function sends @data of length @len to the remote @dst address, * and uses @src as the source address. - * The message will be sent to the remote processor which the @rpdev - * channel belongs to. + * The message will be sent to the remote processor which the @ept + * endpoint belongs to. * In case there are no TX buffers available, the function will immediately * return -ENOMEM without waiting until one becomes available. * @@ -337,9 +345,11 @@ int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) * Returns 0 on success and an appropriate error value on failure. */ static inline -int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, +int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { + struct rpmsg_channel *rpdev = ept->rpdev; + return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); } diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c index 7e17d1c0aaf2..37975eddd64e 100644 --- a/samples/rpmsg/rpmsg_client_sample.c +++ b/samples/rpmsg/rpmsg_client_sample.c @@ -47,7 +47,7 @@ static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, } /* send a new message now */ - ret = rpmsg_send(rpdev, MSG, strlen(MSG)); + ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG)); if (ret) dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); } @@ -67,7 +67,7 @@ static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) dev_set_drvdata(&rpdev->dev, idata); /* send a message to our remote processor */ - ret = rpmsg_send(rpdev, MSG, strlen(MSG)); + ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG)); if (ret) { dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); return ret; -- cgit v1.2.3-59-g8ed1b From 92e1de51bf2cb8d49adc8925abe56ce84911a232 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 1 Sep 2016 15:27:57 -0700 Subject: rpmsg: Clean up rpmsg device vs channel naming The rpmsg device representing struct is called rpmsg_channel and the variable name used throughout is rpdev, with the communication happening on endpoints it's clearer to just call this a "device" in a public API. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/virtio_rpmsg_bus.c | 42 ++++++++++++++++++------------------- include/linux/rpmsg.h | 32 +++++++++++++++------------- samples/rpmsg/rpmsg_client_sample.c | 6 +++--- 3 files changed, 41 insertions(+), 39 deletions(-) (limited to 'samples') diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 7c7c6a8b21d9..1ac9fd871760 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -73,7 +73,7 @@ struct virtproc_info { struct rpmsg_endpoint *ns_ept; }; -#define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev) +#define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev) #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) /* @@ -113,7 +113,7 @@ static ssize_t \ field##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); \ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ \ return sprintf(buf, format_string, rpdev->path); \ } @@ -127,7 +127,7 @@ rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n"); static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name); } @@ -142,7 +142,7 @@ static struct device_attribute rpmsg_dev_attrs[] = { }; /* rpmsg devices and drivers are matched using the service name */ -static inline int rpmsg_id_match(const struct rpmsg_channel *rpdev, +static inline int rpmsg_id_match(const struct rpmsg_device *rpdev, const struct rpmsg_device_id *id) { return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0; @@ -151,7 +151,7 @@ static inline int rpmsg_id_match(const struct rpmsg_channel *rpdev, /* match rpmsg channel and rpmsg driver */ static int rpmsg_dev_match(struct device *dev, struct device_driver *drv) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv); const struct rpmsg_device_id *ids = rpdrv->id_table; unsigned int i; @@ -166,7 +166,7 @@ static int rpmsg_dev_match(struct device *dev, struct device_driver *drv) static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT, rpdev->id.name); @@ -194,7 +194,7 @@ static void __ept_release(struct kref *kref) /* for more info, see below documentation of rpmsg_create_ept() */ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, - struct rpmsg_channel *rpdev, + struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, u32 addr) { @@ -282,7 +282,7 @@ free_ept: * * Returns a pointer to the endpoint on success, or NULL on error. */ -struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, +struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo) { @@ -339,7 +339,7 @@ EXPORT_SYMBOL(rpmsg_destroy_ept); */ static int rpmsg_dev_probe(struct device *dev) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); struct virtproc_info *vrp = rpdev->vrp; struct rpmsg_channel_info chinfo = {}; @@ -387,7 +387,7 @@ out: static int rpmsg_dev_remove(struct device *dev) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); struct virtproc_info *vrp = rpdev->vrp; int err = 0; @@ -451,7 +451,7 @@ EXPORT_SYMBOL(unregister_rpmsg_driver); static void rpmsg_release_device(struct device *dev) { - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); kfree(rpdev); } @@ -461,10 +461,10 @@ static void rpmsg_release_device(struct device *dev) * this is used to make sure we're not creating rpmsg devices for channels * that already exist. */ -static int rpmsg_channel_match(struct device *dev, void *data) +static int rpmsg_device_match(struct device *dev, void *data) { struct rpmsg_channel_info *chinfo = data; - struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); + struct rpmsg_device *rpdev = to_rpmsg_device(dev); if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src) return 0; @@ -484,15 +484,15 @@ static int rpmsg_channel_match(struct device *dev, void *data) * this function will be used to create both static and dynamic * channels. */ -static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp, - struct rpmsg_channel_info *chinfo) +static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp, + struct rpmsg_channel_info *chinfo) { - struct rpmsg_channel *rpdev; + struct rpmsg_device *rpdev; struct device *tmp, *dev = &vrp->vdev->dev; int ret; /* make sure a similar channel doesn't already exist */ - tmp = device_find_child(dev, chinfo, rpmsg_channel_match); + tmp = device_find_child(dev, chinfo, rpmsg_device_match); if (tmp) { /* decrement the matched device's refcount back */ put_device(tmp); @@ -544,7 +544,7 @@ static int rpmsg_destroy_channel(struct virtproc_info *vrp, struct virtio_device *vdev = vrp->vdev; struct device *dev; - dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match); + dev = device_find_child(&vdev->dev, chinfo, rpmsg_device_match); if (!dev) return -EINVAL; @@ -669,7 +669,7 @@ static void rpmsg_downref_sleepers(struct virtproc_info *vrp) * * Returns 0 on success and an appropriate error value on failure. */ -int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, +int rpmsg_send_offchannel_raw(struct rpmsg_device *rpdev, u32 src, u32 dst, void *data, int len, bool wait) { struct virtproc_info *vrp = rpdev->vrp; @@ -879,11 +879,11 @@ static void rpmsg_xmit_done(struct virtqueue *svq) } /* invoked when a name service announcement arrives */ -static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len, +static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { struct rpmsg_ns_msg *msg = data; - struct rpmsg_channel *newch; + struct rpmsg_device *newch; struct rpmsg_channel_info chinfo; struct virtproc_info *vrp = priv; struct device *dev = &vrp->vdev->dev; diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index f278407fcf48..35a0f39fd09b 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -110,7 +110,7 @@ struct rpmsg_channel_info { }; /** - * rpmsg_channel - devices that belong to the rpmsg bus are called channels + * rpmsg_device - device that belong to the rpmsg bus * @vrp: the remote processor this channel belongs to * @dev: the device struct * @id: device id (used to match between rpmsg drivers and devices) @@ -119,7 +119,7 @@ struct rpmsg_channel_info { * @ept: the rpmsg endpoint of this channel * @announce: if set, rpmsg will announce the creation/removal of this channel */ -struct rpmsg_channel { +struct rpmsg_device { struct virtproc_info *vrp; struct device dev; struct rpmsg_device_id id; @@ -129,7 +129,7 @@ struct rpmsg_channel { bool announce; }; -typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, u32); +typedef void (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); /** * struct rpmsg_endpoint - binds a local rpmsg address to its user @@ -155,7 +155,7 @@ typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, u32); * create additional endpoints by themselves (see rpmsg_create_ept()). */ struct rpmsg_endpoint { - struct rpmsg_channel *rpdev; + struct rpmsg_device *rpdev; struct kref refcount; rpmsg_rx_cb_t cb; struct mutex cb_lock; @@ -174,19 +174,21 @@ struct rpmsg_endpoint { struct rpmsg_driver { struct device_driver drv; const struct rpmsg_device_id *id_table; - int (*probe)(struct rpmsg_channel *dev); - void (*remove)(struct rpmsg_channel *dev); - void (*callback)(struct rpmsg_channel *, void *, int, void *, u32); + int (*probe)(struct rpmsg_device *dev); + void (*remove)(struct rpmsg_device *dev); + void (*callback)(struct rpmsg_device *, void *, int, void *, u32); }; +int register_rpmsg_device(struct rpmsg_device *dev); +void unregister_rpmsg_device(struct rpmsg_device *dev); int __register_rpmsg_driver(struct rpmsg_driver *drv, struct module *owner); void unregister_rpmsg_driver(struct rpmsg_driver *drv); void rpmsg_destroy_ept(struct rpmsg_endpoint *); -struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *, +struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *, rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo); int -rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); +rpmsg_send_offchannel_raw(struct rpmsg_device *, u32, u32, void *, int, bool); /* use a macro to avoid include chaining to get THIS_MODULE */ #define register_rpmsg_driver(drv) \ @@ -224,7 +226,7 @@ rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); */ static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; u32 src = ept->addr, dst = rpdev->dst; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); @@ -251,7 +253,7 @@ static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; u32 src = ept->addr; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); @@ -281,7 +283,7 @@ static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); } @@ -306,7 +308,7 @@ int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; u32 src = ept->addr, dst = rpdev->dst; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); @@ -332,7 +334,7 @@ int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; u32 src = ept->addr; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); @@ -361,7 +363,7 @@ static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { - struct rpmsg_channel *rpdev = ept->rpdev; + struct rpmsg_device *rpdev = ept->rpdev; return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); } diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c index 37975eddd64e..4fcd7ee13fb9 100644 --- a/samples/rpmsg/rpmsg_client_sample.c +++ b/samples/rpmsg/rpmsg_client_sample.c @@ -28,7 +28,7 @@ struct instance_data { int rx_count; }; -static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, +static void rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { int ret; @@ -52,7 +52,7 @@ static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); } -static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) +static int rpmsg_sample_probe(struct rpmsg_device *rpdev) { int ret; struct instance_data *idata; @@ -76,7 +76,7 @@ static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) return 0; } -static void rpmsg_sample_remove(struct rpmsg_channel *rpdev) +static void rpmsg_sample_remove(struct rpmsg_device *rpdev) { dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n"); } -- cgit v1.2.3-59-g8ed1b From 4b83c52a21cf5a7421b7c28bebf8ff28ba96ceb9 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 1 Sep 2016 15:28:08 -0700 Subject: rpmsg: Allow callback to return errors Some rpmsg backends support holding on to and redelivering messages upon failed handling of them, so provide a way for the callback to report and error and allow the backends to handle this. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/virtio_rpmsg_bus.c | 10 ++++++---- include/linux/rpmsg.h | 4 ++-- samples/rpmsg/rpmsg_client_sample.c | 6 ++++-- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'samples') diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 671cb1803431..3090b0d3072f 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -791,8 +791,8 @@ static void rpmsg_xmit_done(struct virtqueue *svq) } /* invoked when a name service announcement arrives */ -static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, - void *priv, u32 src) +static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, + void *priv, u32 src) { struct rpmsg_ns_msg *msg = data; struct rpmsg_device *newch; @@ -808,7 +808,7 @@ static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, if (len != sizeof(*msg)) { dev_err(dev, "malformed ns msg (%d)\n", len); - return; + return -EINVAL; } /* @@ -819,7 +819,7 @@ static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, */ if (rpdev) { dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); - return; + return -EINVAL; } /* don't trust the remote processor for null terminating the name */ @@ -842,6 +842,8 @@ static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, if (!newch) dev_err(dev, "rpmsg_create_channel failed\n"); } + + return 0; } static int rpmsg_probe(struct virtio_device *vdev) diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 71b16d37503a..452d393cc8dd 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -80,7 +80,7 @@ struct rpmsg_device { const struct rpmsg_device_ops *ops; }; -typedef void (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); +typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); /** * struct rpmsg_endpoint - binds a local rpmsg address to its user @@ -129,7 +129,7 @@ struct rpmsg_driver { const struct rpmsg_device_id *id_table; int (*probe)(struct rpmsg_device *dev); void (*remove)(struct rpmsg_device *dev); - void (*callback)(struct rpmsg_device *, void *, int, void *, u32); + int (*callback)(struct rpmsg_device *, void *, int, void *, u32); }; int register_rpmsg_device(struct rpmsg_device *dev); diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c index 4fcd7ee13fb9..f161dfd3e70a 100644 --- a/samples/rpmsg/rpmsg_client_sample.c +++ b/samples/rpmsg/rpmsg_client_sample.c @@ -28,7 +28,7 @@ struct instance_data { int rx_count; }; -static void rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len, +static int rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { int ret; @@ -43,13 +43,15 @@ static void rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len, /* samples should not live forever */ if (idata->rx_count >= MSG_LIMIT) { dev_info(&rpdev->dev, "goodbye!\n"); - return; + return 0; } /* send a new message now */ ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG)); if (ret) dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); + + return 0; } static int rpmsg_sample_probe(struct rpmsg_device *rpdev) -- cgit v1.2.3-59-g8ed1b