Module: xenomai-3
Branch: next
Commit: 4c407f8b657229e208ba4a056f685b035c3baf0f
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=4c407f8b657229e208ba4a056f685b035c3baf0f

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

Reply via email to