Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 9a4978e5ecda81d6db9e8b8d8d67f9de49db43ef URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9a4978e5ecda81d6db9e8b8d8d67f9de49db43ef
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Dec 5 15:34:17 2017 +0100 net/iovec: add copy iterators for iovec[] --- kernel/drivers/net/stack/include/rtnet_iovec.h | 8 +++ kernel/drivers/net/stack/iovec.c | 79 +++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/net/stack/include/rtnet_iovec.h b/kernel/drivers/net/stack/include/rtnet_iovec.h index 2b81893..09e86d1 100644 --- a/kernel/drivers/net/stack/include/rtnet_iovec.h +++ b/kernel/drivers/net/stack/include/rtnet_iovec.h @@ -25,6 +25,8 @@ #include <linux/uio.h> +struct user_msghdr; +struct rtdm_fd; /*** * rt_iovec_len @@ -44,7 +46,13 @@ static inline size_t rt_iovec_len(const struct iovec *iov, int iovlen) extern void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len); extern void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov, int len); +ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + const void *data, size_t len); +ssize_t rtnet_read_from_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + void *data, size_t len); #endif /* __KERNEL__ */ #endif /* __RTNET_IOVEC_H_ */ diff --git a/kernel/drivers/net/stack/iovec.c b/kernel/drivers/net/stack/iovec.c index 24efa87..3164d28 100644 --- a/kernel/drivers/net/stack/iovec.c +++ b/kernel/drivers/net/stack/iovec.c @@ -25,8 +25,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/string.h> - +#include <rtdm/driver.h> #include <rtnet_iovec.h> +#include <rtnet_socket.h> /*** @@ -49,6 +50,7 @@ void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len) iov++; } } +EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec); /*** @@ -71,7 +73,78 @@ void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov,int len) iov++; } } +EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec); +ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + const void *data, size_t len) +{ + ssize_t ret = 0; + size_t nbytes; + int n; -EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec); -EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec); + for (n = 0; len > 0 && n < iovlen; n++, iov++) { + if (iov->iov_len == 0) + continue; + + nbytes = iov->iov_len; + if (nbytes > len) + nbytes = len; + + ret = rtnet_put_arg(fd, iov->iov_base, data, nbytes); + if (ret) + break; + + len -= nbytes; + data += nbytes; + iov->iov_len -= nbytes; + iov->iov_base += nbytes; + ret += nbytes; + if (ret < 0) { + ret = -EINVAL; + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(rtnet_write_to_iov); + +ssize_t rtnet_read_from_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + void *data, size_t len) +{ + ssize_t ret = 0; + size_t nbytes; + int n; + + for (n = 0; len > 0 && n < iovlen; n++, iov++) { + if (iov->iov_len == 0) + continue; + + nbytes = iov->iov_len; + if (nbytes > len) + nbytes = len; + + if (!rtdm_fd_is_user(fd)) + memcpy(data, iov->iov_base, nbytes); + else { + ret = rtdm_copy_from_user(fd, data, iov->iov_base, nbytes); + if (ret) + break; + } + + len -= nbytes; + data += nbytes; + iov->iov_len -= nbytes; + iov->iov_base += nbytes; + ret += nbytes; + if (ret < 0) { + ret = -EINVAL; + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(rtnet_read_from_iov); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git