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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Oct 22 15:20:21 2014 +0200

drivers/rtipc: fixup for 32bit emulation

---

 kernel/drivers/ipc/bufp.c     |  115 ++++++-------
 kernel/drivers/ipc/iddp.c     |  123 +++++++-------
 kernel/drivers/ipc/internal.h |   41 ++++-
 kernel/drivers/ipc/rtipc.c    |  365 ++++++++++++++++++++++++++++++++++++-----
 kernel/drivers/ipc/xddp.c     |  113 ++++++-------
 5 files changed, 520 insertions(+), 237 deletions(-)

diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 1e5ecf3..5ae166a 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -375,17 +375,16 @@ static ssize_t bufp_recvmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __bufp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr);
        if (ret <= 0)
                return ret;
 
        /* Copy the updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
+       if (rtipc_put_iovec(fd, iov, msg))
                return -EFAULT;
 
        /* Copy the source address if required. */
@@ -620,8 +619,7 @@ static ssize_t bufp_sendmsg(struct rtdm_fd *fd,
                        return -EINVAL;
 
                /* Fetch the destination address to send to. */
-               if (rtipc_get_arg(fd, &daddr,
-                                 msg->msg_name, sizeof(daddr)))
+               if (rtipc_get_arg(fd, &daddr, msg->msg_name, sizeof(daddr)))
                        return -EFAULT;
 
                if (daddr.sipc_port < 0 ||
@@ -639,20 +637,16 @@ static ssize_t bufp_sendmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __bufp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr);
        if (ret <= 0)
                return ret;
 
        /* Copy updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
-
-       return ret;
+       return rtipc_put_iovec(fd, iov, msg) ?: ret;
 }
 
 static ssize_t bufp_write(struct rtdm_fd *fd,
@@ -829,30 +823,27 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
        struct rtipc_port_label plabel;
        struct timeval tv;
        rtdm_lockctx_t s;
-       int ret = 0;
        size_t len;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptin(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
        if (sopt.level == SOL_SOCKET) {
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (sopt.optlen != sizeof(tv))
-                               return -EINVAL;
-                       if (rtipc_get_arg(fd, &tv,
-                                         sopt.optval, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_get_timeval(fd, &tv, sopt.optval, 
sopt.optlen);
+                       if (ret)
+                               return ret;
                        sk->rx_timeout = rtipc_timeval_to_ns(&tv);
                        break;
 
                case SO_SNDTIMEO:
-                       if (sopt.optlen != sizeof(tv))
-                               return -EINVAL;
-                       if (rtipc_get_arg(fd, &tv,
-                                         sopt.optval, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_get_timeval(fd, &tv, sopt.optval, 
sopt.optlen);
+                       if (ret)
+                               return ret;
                        sk->tx_timeout = rtipc_timeval_to_ns(&tv);
                        break;
 
@@ -869,11 +860,9 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
        switch (sopt.optname) {
 
        case BUFP_BUFSZ:
-               if (sopt.optlen != sizeof(len))
-                       return -EINVAL;
-               if (rtipc_get_arg(fd, &len,
-                                 sopt.optval, sizeof(len)))
-                       return -EFAULT;
+               ret = rtipc_get_length(fd, &len, sopt.optval, sopt.optlen);
+               if (ret)
+                       return ret;
                if (len == 0)
                        return -EINVAL;
                cobalt_atomic_enter(s);
@@ -892,8 +881,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
        case BUFP_LABEL:
                if (sopt.optlen < sizeof(plabel))
                        return -EINVAL;
-               if (rtipc_get_arg(fd, &plabel,
-                                 sopt.optval, sizeof(plabel)))
+               if (rtipc_get_arg(fd, &plabel, sopt.optval, sizeof(plabel)))
                        return -EFAULT;
                cobalt_atomic_enter(s);
                /*
@@ -925,10 +913,11 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
        struct timeval tv;
        rtdm_lockctx_t s;
        socklen_t len;
-       int ret = 0;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptout(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
        if (rtipc_get_arg(fd, &len, sopt.optlen, sizeof(len)))
                return -EFAULT;
@@ -937,21 +926,17 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (len != sizeof(tv))
-                               return -EINVAL;
                        rtipc_ns_to_timeval(&tv, sk->rx_timeout);
-                       if (rtipc_put_arg(fd, sopt.optval,
-                                         &tv, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
+                       if (ret)
+                               return ret;
                        break;
 
                case SO_SNDTIMEO:
-                       if (len != sizeof(tv))
-                               return -EINVAL;
                        rtipc_ns_to_timeval(&tv, sk->tx_timeout);
-                       if (rtipc_put_arg(fd, sopt.optval,
-                                         &tv, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
+                       if (ret)
+                               return ret;
                        break;
 
                default:
@@ -972,8 +957,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
                cobalt_atomic_enter(s);
                strcpy(plabel.label, sk->label);
                cobalt_atomic_leave(s);
-               if (rtipc_put_arg(fd, sopt.optval,
-                                 &plabel, sizeof(plabel)))
+               if (rtipc_put_arg(fd, sopt.optval, &plabel, sizeof(plabel)))
                        return -EFAULT;
                break;
 
@@ -994,15 +978,15 @@ static int __bufp_ioctl(struct rtdm_fd *fd,
 
        switch (request) {
 
-       case _RTIOC_CONNECT:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_CONNECT):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret)
                  return ret;
                ret = __bufp_connect_socket(sk, saddrp);
                break;
 
-       case _RTIOC_BIND:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_BIND):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret)
                        return ret;
                if (saddrp == NULL)
@@ -1010,24 +994,24 @@ static int __bufp_ioctl(struct rtdm_fd *fd,
                ret = __bufp_bind_socket(priv, saddrp);
                break;
 
-       case _RTIOC_GETSOCKNAME:
+       COMPAT_CASE(_RTIOC_GETSOCKNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->name);
                break;
 
-       case _RTIOC_GETPEERNAME:
+       COMPAT_CASE(_RTIOC_GETPEERNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->peer);
                break;
 
-       case _RTIOC_SETSOCKOPT:
+       COMPAT_CASE(_RTIOC_SETSOCKOPT):
                ret = __bufp_setsockopt(sk, fd, arg);
                break;
 
-       case _RTIOC_GETSOCKOPT:
+       COMPAT_CASE(_RTIOC_GETSOCKOPT):
                ret = __bufp_getsockopt(sk, fd, arg);
                break;
 
        case _RTIOC_LISTEN:
-       case _RTIOC_ACCEPT:
+       COMPAT_CASE(_RTIOC_ACCEPT):
                ret = -EOPNOTSUPP;
                break;
 
@@ -1045,10 +1029,17 @@ static int __bufp_ioctl(struct rtdm_fd *fd,
 static int bufp_ioctl(struct rtdm_fd *fd,
                      unsigned int request, void *arg)
 {
-       if (rtdm_in_rt_context() && request == _RTIOC_BIND)
-               return -ENOSYS; /* Try downgrading to NRT */
+       int ret;
 
-       return __bufp_ioctl(fd, request, arg);
+       switch (request) {
+       COMPAT_CASE(_RTIOC_BIND):
+               if (rtdm_in_rt_context())
+                       return -ENOSYS; /* Try downgrading to NRT */
+       default:
+               ret = __bufp_ioctl(fd, request, arg);
+       }
+
+       return ret;
 }
 
 static unsigned int bufp_pollstate(struct rtdm_fd *fd)
diff --git a/kernel/drivers/ipc/iddp.c b/kernel/drivers/ipc/iddp.c
index a2406da..d37c784 100644
--- a/kernel/drivers/ipc/iddp.c
+++ b/kernel/drivers/ipc/iddp.c
@@ -344,23 +344,21 @@ static ssize_t iddp_recvmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __iddp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr);
        if (ret <= 0)
                return ret;
 
        /* Copy the updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
+       if (rtipc_put_iovec(fd, iov, msg))
                return -EFAULT;
 
        /* Copy the source address if required. */
        if (msg->msg_name) {
-               if (rtipc_put_arg(fd, msg->msg_name,
-                                 &saddr, sizeof(saddr)))
+               if (rtipc_put_arg(fd, msg->msg_name, &saddr, sizeof(saddr)))
                        return -EFAULT;
                msg->msg_namelen = sizeof(struct sockaddr_ipc);
        }
@@ -484,8 +482,7 @@ static ssize_t iddp_sendmsg(struct rtdm_fd *fd,
                        return -EINVAL;
 
                /* Fetch the destination address to send to. */
-               if (rtipc_get_arg(fd, &daddr,
-                                 msg->msg_name, sizeof(daddr)))
+               if (rtipc_get_arg(fd, &daddr, msg->msg_name, sizeof(daddr)))
                        return -EFAULT;
 
                if (daddr.sipc_port < 0 ||
@@ -503,20 +500,16 @@ static ssize_t iddp_sendmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __iddp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr);
        if (ret <= 0)
                return ret;
 
        /* Copy updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
-
-       return ret;
+       return rtipc_put_iovec(fd, iov, msg) ?: ret;
 }
 
 static ssize_t iddp_write(struct rtdm_fd *fd,
@@ -706,30 +699,27 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
        struct rtipc_port_label plabel;
        struct timeval tv;
        rtdm_lockctx_t s;
-       int ret = 0;
        size_t len;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptin(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
        if (sopt.level == SOL_SOCKET) {
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (sopt.optlen != sizeof(tv))
-                               return -EINVAL;
-                       if (rtipc_get_arg(fd, &tv,
-                                         sopt.optval, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_get_timeval(fd, &tv, sopt.optval, 
sopt.optlen);
+                       if (ret)
+                               return ret;
                        sk->rx_timeout = rtipc_timeval_to_ns(&tv);
                        break;
 
                case SO_SNDTIMEO:
-                       if (sopt.optlen != sizeof(tv))
-                               return -EINVAL;
-                       if (rtipc_get_arg(fd, &tv,
-                                         sopt.optval, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_get_timeval(fd, &tv, sopt.optval, 
sopt.optlen);
+                       if (ret)
+                               return ret;
                        sk->tx_timeout = rtipc_timeval_to_ns(&tv);
                        break;
 
@@ -746,11 +736,9 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
        switch (sopt.optname) {
 
        case IDDP_POOLSZ:
-               if (sopt.optlen != sizeof(len))
-                       return -EINVAL;
-               if (rtipc_get_arg(fd, &len,
-                                 sopt.optval, sizeof(len)))
-                       return -EFAULT;
+               ret = rtipc_get_length(fd, &len, sopt.optval, sopt.optlen);
+               if (ret)
+                       return ret;
                if (len == 0)
                        return -EINVAL;
                cobalt_atomic_enter(s);
@@ -769,8 +757,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
        case IDDP_LABEL:
                if (sopt.optlen < sizeof(plabel))
                        return -EINVAL;
-               if (rtipc_get_arg(fd, &plabel,
-                                 sopt.optval, sizeof(plabel)))
+               if (rtipc_get_arg(fd, &plabel, sopt.optval, sizeof(plabel)))
                        return -EFAULT;
                cobalt_atomic_enter(s);
                /*
@@ -802,33 +789,31 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
        struct timeval tv;
        rtdm_lockctx_t s;
        socklen_t len;
-       int ret = 0;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptout(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
-       if (rtipc_get_arg(fd, &len, sopt.optlen, sizeof(len)))
-               return -EFAULT;
+       ret = rtipc_get_arg(fd, &len, sopt.optlen, sizeof(len));
+       if (ret)
+               return ret;
 
        if (sopt.level == SOL_SOCKET) {
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (len != sizeof(tv))
-                               return -EINVAL;
                        rtipc_ns_to_timeval(&tv, sk->rx_timeout);
-                       if (rtipc_put_arg(fd, sopt.optval,
-                                         &tv, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
+                       if (ret)
+                               return ret;
                        break;
 
                case SO_SNDTIMEO:
-                       if (len != sizeof(tv))
-                               return -EINVAL;
                        rtipc_ns_to_timeval(&tv, sk->tx_timeout);
-                       if (rtipc_put_arg(fd, sopt.optval,
-                                         &tv, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
+                       if (ret)
+                               return ret;
                        break;
 
                default:
@@ -849,8 +834,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
                cobalt_atomic_enter(s);
                strcpy(plabel.label, sk->label);
                cobalt_atomic_leave(s);
-               if (rtipc_put_arg(fd, sopt.optval,
-                                 &plabel, sizeof(plabel)))
+               if (rtipc_put_arg(fd, sopt.optval, &plabel, sizeof(plabel)))
                        return -EFAULT;
                break;
 
@@ -871,15 +855,15 @@ static int __iddp_ioctl(struct rtdm_fd *fd,
 
        switch (request) {
 
-       case _RTIOC_CONNECT:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_CONNECT):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret)
                  return ret;
                ret = __iddp_connect_socket(sk, saddrp);
                break;
 
-       case _RTIOC_BIND:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_BIND):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret)
                        return ret;
                if (saddrp == NULL)
@@ -887,24 +871,24 @@ static int __iddp_ioctl(struct rtdm_fd *fd,
                ret = __iddp_bind_socket(fd, saddrp);
                break;
 
-       case _RTIOC_GETSOCKNAME:
+       COMPAT_CASE(_RTIOC_GETSOCKNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->name);
                break;
 
-       case _RTIOC_GETPEERNAME:
+       COMPAT_CASE(_RTIOC_GETPEERNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->peer);
                break;
 
-       case _RTIOC_SETSOCKOPT:
+       COMPAT_CASE(_RTIOC_SETSOCKOPT):
                ret = __iddp_setsockopt(sk, fd, arg);
                break;
 
-       case _RTIOC_GETSOCKOPT:
+       COMPAT_CASE(_RTIOC_GETSOCKOPT):
                ret = __iddp_getsockopt(sk, fd, arg);
                break;
 
        case _RTIOC_LISTEN:
-       case _RTIOC_ACCEPT:
+       COMPAT_CASE(_RTIOC_ACCEPT):
                ret = -EOPNOTSUPP;
                break;
 
@@ -922,10 +906,17 @@ static int __iddp_ioctl(struct rtdm_fd *fd,
 static int iddp_ioctl(struct rtdm_fd *fd,
                      unsigned int request, void *arg)
 {
-       if (rtdm_in_rt_context() && request == _RTIOC_BIND)
-               return -ENOSYS; /* Try downgrading to NRT */
+       int ret;
 
-       return __iddp_ioctl(fd, request, arg);
+       switch (request) {
+       COMPAT_CASE(_RTIOC_BIND):
+               if (rtdm_in_rt_context())
+                       return -ENOSYS; /* Try downgrading to NRT */
+       default:
+               ret = __iddp_ioctl(fd, request, arg);
+       }
+
+       return ret;
 }
 
 static int iddp_init(void)
diff --git a/kernel/drivers/ipc/internal.h b/kernel/drivers/ipc/internal.h
index b857a40..aeb7abd 100644
--- a/kernel/drivers/ipc/internal.h
+++ b/kernel/drivers/ipc/internal.h
@@ -24,6 +24,7 @@
 #include <cobalt/kernel/clock.h>
 #include <cobalt/kernel/select.h>
 #include <rtdm/rtdm.h>
+#include <rtdm/compat.h>
 #include <rtdm/driver.h>
 
 #define RTIPC_IOV_MAX  64
@@ -83,18 +84,45 @@ static inline void rtipc_ns_to_timeval(struct timeval *tv, 
nanosecs_rel_t ns)
        tv->tv_usec = nsecs / 1000;
 }
 
-int rtipc_get_arg(struct rtdm_fd *fd,
-                 void *dst, const void *src, size_t len);
+int rtipc_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
+                   const struct msghdr *msg);
 
-int rtipc_put_arg(struct rtdm_fd *fd,
-                 void *dst, const void *src, size_t len);
+int rtipc_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
+                   const struct msghdr *msg);
 
 int rtipc_get_sockaddr(struct rtdm_fd *fd,
-                      const void *arg, struct sockaddr_ipc **saddrp);
+                      struct sockaddr_ipc **saddrp,
+                      const void *arg);
 
 int rtipc_put_sockaddr(struct rtdm_fd *fd, void *arg,
                       const struct sockaddr_ipc *saddr);
 
+int rtipc_get_sockoptout(struct rtdm_fd *fd,
+                        struct _rtdm_getsockopt_args *sopt,
+                        const void *arg);
+
+int rtipc_put_sockoptout(struct rtdm_fd *fd, void *arg,
+                        const struct _rtdm_getsockopt_args *sopt);
+
+int rtipc_get_sockoptin(struct rtdm_fd *fd,
+                       struct _rtdm_setsockopt_args *sopt,
+                       const void *arg);
+
+int rtipc_get_timeval(struct rtdm_fd *fd, struct timeval *tv,
+                     const void *arg, size_t arglen);
+
+int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
+                     const struct timeval *tv, size_t arglen);
+
+int rtipc_get_length(struct rtdm_fd *fd, size_t *lenp,
+                    const void *arg, size_t arglen);
+
+int rtipc_get_arg(struct rtdm_fd *fd, void *dst, const void *src,
+                 size_t len);
+
+int rtipc_put_arg(struct rtdm_fd *fd, void *dst, const void *src,
+                 size_t len);
+
 ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen);
 
 extern struct rtipc_protocol xddp_proto_driver;
@@ -108,7 +136,8 @@ extern struct xnptree rtipc_ptree;
 #define rtipc_wait_context             xnthread_wait_context
 #define rtipc_prepare_wait             xnthread_prepare_wait
 #define rtipc_get_wait_context         xnthread_get_wait_context
-
 #define rtipc_peek_wait_head(obj)      xnsynch_peek_pendq(&(obj)->synch_base)
 
+#define COMPAT_CASE(__op)      case __op __COMPAT_CASE(__op  ## _COMPAT)
+
 #endif /* !_RTIPC_INTERNAL_H */
diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c
index c0ea808..4c569c7 100644
--- a/kernel/drivers/ipc/rtipc.c
+++ b/kernel/drivers/ipc/rtipc.c
@@ -42,51 +42,139 @@ static struct rtipc_protocol *protocols[IPCPROTO_MAX] = {
 
 DEFINE_XNPTREE(rtipc_ptree, "rtipc");
 
-int rtipc_get_arg(struct rtdm_fd *fd,
-                 void *dst, const void *src, size_t len)
+int rtipc_get_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
 {
-       if (rtdm_fd_is_user(fd)) {
-               if (rtdm_safe_copy_from_user(fd, dst, src, len))
-                       return -EFAULT;
-       } else
+       if (!rtdm_fd_is_user(fd)) {
                memcpy(dst, src, len);
+               return 0;
+       }
 
-       return 0;
+       return rtdm_copy_from_user(fd, dst, src, len);
 }
 
-int rtipc_put_arg(struct rtdm_fd *fd,
-                 void *dst, const void *src, size_t len)
+int rtipc_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
 {
-       if (rtdm_fd_is_user(fd)) {
-               if (rtdm_safe_copy_to_user(fd, dst, src, len))
-                       return -EFAULT;
-       } else
+       if (!rtdm_fd_is_user(fd)) {
                memcpy(dst, src, len);
+               return 0;
+       }
 
-       return 0;
+       return rtdm_copy_to_user(fd, dst, src, len);
 }
 
-int rtipc_get_sockaddr(struct rtdm_fd *fd,
-                      const void *arg, struct sockaddr_ipc **saddrp)
+int rtipc_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
+                   const struct msghdr *msg)
 {
-       struct _rtdm_setsockaddr_args setaddr;
+       size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+       if (!rtdm_fd_is_user(fd)) {
+               memcpy(iov, msg->msg_iov, len);
+               return 0;
+       }
 
-       if (rtipc_get_arg(fd,
-                         &setaddr, arg, sizeof(setaddr)))
-               return -EFAULT;
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_iovec ciov, __user *p;
+               int ret, n;
+               for (n = 0, p = (struct compat_iovec *)msg->msg_iov;
+                    n < msg->msg_iovlen; n++, p++) {
+                       ret = rtdm_copy_from_user(fd, &ciov, p, sizeof(ciov));
+                       if (ret)
+                               return ret;
+                       iov[n].iov_base = compat_ptr(ciov.iov_base);
+                       iov[n].iov_len = ciov.iov_len;
+               }
+               return 0;
+       }
+#endif
 
-       if (setaddr.addrlen > 0) {
-               if (setaddr.addrlen != sizeof(**saddrp))
-                       return -EINVAL;
+       return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+
+int rtipc_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
+                   const struct msghdr *msg)
+{
+       size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+
+       if (!rtdm_fd_is_user(fd)) {
+               memcpy(msg->msg_iov, iov, len);
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_iovec ciov, __user *p;
+               int ret, n;
+               for (n = 0, p = (struct compat_iovec *)msg->msg_iov;
+                    n < msg->msg_iovlen; n++, p++) {
+                       ciov.iov_base = ptr_to_compat(iov[n].iov_base);
+                       ciov.iov_len = iov[n].iov_len;
+                       ret = rtdm_copy_to_user(fd, p, &ciov, sizeof(*p));
+                       if (ret)
+                               return ret;
+               }
+               return 0;
+       }
+#endif
+
+       return rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+}
+
+int rtipc_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_ipc **saddrp,
+                      const void *arg)
+{
+       const struct _rtdm_setsockaddr_args *p;
+       struct _rtdm_setsockaddr_args sreq;
+       int ret;
 
-               if (rtipc_get_arg(fd, *saddrp,
-                                 setaddr.addr, sizeof(**saddrp)))
-                       return -EFAULT;
-       } else {
-               if (setaddr.addr)
+       if (!rtdm_fd_is_user(fd)) {
+               p = arg;
+               if (p->addrlen > 0) {
+                       if (p->addrlen != sizeof(**saddrp))
+                               return -EINVAL;
+                       memcpy(*saddrp, p->addr, sizeof(**saddrp));
+               } else {
+                       if (p->addr)
+                               return -EINVAL;
+                       *saddrp = NULL;
+               }
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_rtdm_setsockaddr_args csreq;
+               ret = rtdm_safe_copy_from_user(fd, &csreq, arg, sizeof(csreq));
+               if (ret)
+                       return ret;
+               if (csreq.addrlen > 0) {
+                       if (csreq.addrlen != sizeof(**saddrp))
+                               return -EINVAL;
+                       return rtdm_safe_copy_from_user(fd, *saddrp,
+                                                       compat_ptr(csreq.addr),
+                                                       sizeof(**saddrp));
+               }
+               if (csreq.addr)
                        return -EINVAL;
+
                *saddrp = NULL;
+
+               return 0;
        }
+#endif
+
+       ret = rtdm_safe_copy_from_user(fd, &sreq, arg, sizeof(sreq));
+       if (ret)
+               return ret;
+       if (sreq.addrlen > 0) {
+               if (sreq.addrlen != sizeof(**saddrp))
+                       return -EINVAL;
+               return rtdm_safe_copy_from_user(fd, *saddrp,
+                                               sreq.addr, sizeof(**saddrp));
+       }
+       if (sreq.addr)
+               return -EINVAL;
+
+       *saddrp = NULL;
 
        return 0;
 }
@@ -94,30 +182,223 @@ int rtipc_get_sockaddr(struct rtdm_fd *fd,
 int rtipc_put_sockaddr(struct rtdm_fd *fd, void *arg,
                       const struct sockaddr_ipc *saddr)
 {
-       struct _rtdm_getsockaddr_args getaddr;
+       const struct _rtdm_getsockaddr_args *p;
+       struct _rtdm_getsockaddr_args sreq;
        socklen_t len;
+       int ret;
 
-       if (rtipc_get_arg(fd,
-                         &getaddr, arg, sizeof(getaddr)))
-               return -EFAULT;
+       if (!rtdm_fd_is_user(fd)) {
+               p = arg;
+               if (*p->addrlen < sizeof(*saddr))
+                       return -EINVAL;
+               memcpy(p->addr, saddr, sizeof(*saddr));
+               *p->addrlen = sizeof(*saddr);
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_rtdm_getsockaddr_args csreq;
+               ret = rtdm_safe_copy_from_user(fd, &csreq, arg, sizeof(csreq));
+               if (ret)
+                       return ret;
+
+               ret = rtdm_safe_copy_from_user(fd, &len,
+                                              compat_ptr(csreq.addrlen),
+                                              sizeof(len));
+               if (ret)
+                       return ret;
+
+               if (len < sizeof(*saddr))
+                       return -EINVAL;
+
+               ret = rtdm_safe_copy_to_user(fd, compat_ptr(csreq.addr),
+                                            saddr, sizeof(*saddr));
+               if (ret)
+                       return ret;
+
+               len = sizeof(*saddr);
+               return rtdm_safe_copy_to_user(fd, compat_ptr(csreq.addrlen),
+                                             &len, sizeof(len));
+       }
+#endif
+
+       ret = rtdm_safe_copy_from_user(fd, &sreq, arg, sizeof(sreq));
+       if (ret)
+               return ret;
 
-       if (rtipc_get_arg(fd,
-                         &len, getaddr.addrlen, sizeof(len)))
-               return -EFAULT;
+       ret = rtdm_safe_copy_from_user(fd, &len, sreq.addrlen, sizeof(len));
+       if (ret)
+               return ret;
 
        if (len < sizeof(*saddr))
                return -EINVAL;
 
-       if (rtipc_put_arg(fd,
-                         getaddr.addr, saddr, sizeof(*saddr)))
-               return -EFAULT;
+       ret = rtdm_safe_copy_to_user(fd, sreq.addr, saddr, sizeof(*saddr));
+       if (ret)
+               return ret;
 
        len = sizeof(*saddr);
-       if (rtipc_put_arg(fd,
-                         getaddr.addrlen, &len, sizeof(len)))
-               return -EFAULT;
 
-       return 0;
+       return rtdm_safe_copy_to_user(fd, sreq.addrlen, &len, sizeof(len));
+}
+
+int rtipc_get_sockoptout(struct rtdm_fd *fd, struct _rtdm_getsockopt_args 
*sopt,
+                        const void *arg)
+{
+       if (!rtdm_fd_is_user(fd)) {
+               *sopt = *(struct _rtdm_getsockopt_args *)arg;
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_rtdm_getsockopt_args csopt;
+               int ret;
+               ret = rtdm_safe_copy_from_user(fd, &csopt, arg, sizeof(csopt));
+               if (ret)
+                       return ret;
+               sopt->level = csopt.level;
+               sopt->optname = csopt.optname;
+               sopt->optval = compat_ptr(csopt.optval);
+               sopt->optlen = compat_ptr(csopt.optlen);
+               return 0;
+       }
+#endif
+
+       return rtdm_safe_copy_from_user(fd, sopt, arg, sizeof(*sopt));
+}
+
+int rtipc_put_sockoptout(struct rtdm_fd *fd, void *arg,
+                        const struct _rtdm_getsockopt_args *sopt)
+{
+       if (!rtdm_fd_is_user(fd)) {
+               *(struct _rtdm_getsockopt_args *)arg = *sopt;
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_rtdm_getsockopt_args csopt;
+               int ret;
+               csopt.level = sopt->level;
+               csopt.optname = sopt->optname;
+               csopt.optval = ptr_to_compat(sopt->optval);
+               csopt.optlen = ptr_to_compat(sopt->optlen);
+               ret = rtdm_safe_copy_to_user(fd, arg, &csopt, sizeof(csopt));
+               if (ret)
+                       return ret;
+               return 0;
+       }
+#endif
+
+       return rtdm_safe_copy_to_user(fd, arg, sopt, sizeof(*sopt));
+}
+
+int rtipc_get_sockoptin(struct rtdm_fd *fd, struct _rtdm_setsockopt_args *sopt,
+                       const void *arg)
+{
+       if (!rtdm_fd_is_user(fd)) {
+               *sopt = *(struct _rtdm_setsockopt_args *)arg;
+               return 0;
+       }
+
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_rtdm_setsockopt_args csopt;
+               int ret;
+               ret = rtdm_safe_copy_from_user(fd, &csopt, arg, sizeof(csopt));
+               if (ret)
+                       return ret;
+               sopt->level = csopt.level;
+               sopt->optname = csopt.optname;
+               sopt->optval = compat_ptr(csopt.optval);
+               sopt->optlen = csopt.optlen;
+               return 0;
+       }
+#endif
+
+       return rtdm_safe_copy_from_user(fd, sopt, arg, sizeof(*sopt));
+}
+
+int rtipc_get_timeval(struct rtdm_fd *fd, struct timeval *tv,
+                     const void *arg, size_t arglen)
+{
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               const struct compat_timeval *ctv;
+               if (arglen != sizeof(*ctv))
+                       return -EINVAL;
+               ctv = arg;
+               return (ctv == NULL ||
+                       !access_rok(ctv, sizeof(*ctv)) ||
+                       __xn_get_user(tv->tv_sec, &ctv->tv_sec) ||
+                       __xn_get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 
0;
+       }
+#endif
+
+       if (arglen != sizeof(*tv))
+               return -EINVAL;
+
+       if (!rtdm_fd_is_user(fd)) {
+               *tv = *(struct timeval *)arg;
+               return 0;
+       }
+
+       return rtdm_safe_copy_from_user(fd, tv, arg, sizeof(*tv));
+}
+
+int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
+                     const struct timeval *tv, size_t arglen)
+{
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               struct compat_timeval *ctv;
+               if (arglen != sizeof(*ctv))
+                       return -EINVAL;
+               ctv = arg;
+               return (ctv == NULL ||
+                       !access_wok(ctv, sizeof(*ctv)) ||
+                       __xn_put_user(tv->tv_sec, &ctv->tv_sec) ||
+                       __xn_put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 
0;
+       }
+#endif
+
+       if (arglen != sizeof(*tv))
+               return -EINVAL;
+
+       if (!rtdm_fd_is_user(fd)) {
+               *(struct timeval *)arg = *tv;
+               return 0;
+       }
+
+       return rtdm_safe_copy_to_user(fd, arg, tv, sizeof(*tv));
+}
+
+int rtipc_get_length(struct rtdm_fd *fd, size_t *lenp,
+                    const void *arg, size_t arglen)
+{
+#ifdef CONFIG_COMPAT
+       if (rtdm_fd_is_compat(fd)) {
+               const compat_size_t *csz;
+               if (arglen != sizeof(*csz))
+                       return -EINVAL;
+               csz = arg;
+               return csz == NULL ||
+                       !access_rok(csz, sizeof(*csz)) ||
+                       __xn_get_user(*lenp, csz) ? -EFAULT : 0;
+       }
+#endif
+
+       if (arglen != sizeof(size_t))
+               return -EINVAL;
+
+       if (!rtdm_fd_is_user(fd)) {
+               *lenp = *(size_t *)arg;
+               return 0;
+       }
+
+       return rtdm_safe_copy_from_user(fd, lenp, arg, sizeof(*lenp));
 }
 
 ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen)
diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c
index aa6704a..8f1333d 100644
--- a/kernel/drivers/ipc/xddp.c
+++ b/kernel/drivers/ipc/xddp.c
@@ -349,23 +349,21 @@ static ssize_t xddp_recvmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __xddp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr);
        if (ret <= 0)
                return ret;
 
        /* Copy the updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
+       if (rtipc_put_iovec(fd, iov, msg))
                return -EFAULT;
 
        /* Copy the source address if required. */
        if (msg->msg_name) {
-               if (rtipc_put_arg(fd, msg->msg_name,
-                                 &saddr, sizeof(saddr)))
+               if (rtipc_put_arg(fd, msg->msg_name, &saddr, sizeof(saddr)))
                        return -EFAULT;
                msg->msg_namelen = sizeof(struct sockaddr_ipc);
        }
@@ -619,8 +617,7 @@ static ssize_t xddp_sendmsg(struct rtdm_fd *fd,
                        return -EINVAL;
 
                /* Fetch the destination address to send to. */
-               if (rtipc_get_arg(fd, &daddr,
-                                 msg->msg_name, sizeof(daddr)))
+               if (rtipc_get_arg(fd, &daddr, msg->msg_name, sizeof(daddr)))
                        return -EFAULT;
 
                if (daddr.sipc_port < 0 ||
@@ -638,20 +635,16 @@ static ssize_t xddp_sendmsg(struct rtdm_fd *fd,
                return -EINVAL;
 
        /* Copy I/O vector in */
-       if (rtipc_get_arg(fd, iov, msg->msg_iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
+       ret = rtipc_get_iovec(fd, iov, msg);
+       if (ret)
+               return ret;
 
        ret = __xddp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr);
        if (ret <= 0)
                return ret;
 
        /* Copy updated I/O vector back */
-       if (rtipc_put_arg(fd, msg->msg_iov, iov,
-                         sizeof(iov[0]) * msg->msg_iovlen))
-               return -EFAULT;
-
-       return ret;
+       return rtipc_put_iovec(fd, iov, msg) ?: ret;
 }
 
 static ssize_t xddp_write(struct rtdm_fd *fd,
@@ -860,21 +853,20 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
        struct rtipc_port_label plabel;
        struct timeval tv;
        rtdm_lockctx_t s;
-       int ret = 0;
        size_t len;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptin(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
        if (sopt.level == SOL_SOCKET) {
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (sopt.optlen != sizeof(tv))
-                               return -EINVAL;
-                       if (rtipc_get_arg(fd, &tv,
-                                         sopt.optval, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_get_timeval(fd, &tv, sopt.optval, 
sopt.optlen);
+                       if (ret)
+                               return ret;
                        sk->timeout = rtipc_timeval_to_ns(&tv);
                        break;
 
@@ -891,11 +883,9 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
        switch (sopt.optname) {
 
        case XDDP_BUFSZ:
-               if (sopt.optlen != sizeof(len))
-                       return -EINVAL;
-               if (rtipc_get_arg(fd, &len,
-                                 sopt.optval, sizeof(len)))
-                       return -EFAULT;
+               ret = rtipc_get_length(fd, &len, sopt.optval, sopt.optlen);
+               if (ret)
+                       return ret;
                if (len > 0) {
                        len += sizeof(struct xddp_message);
                        if (sk->bufpool &&
@@ -913,11 +903,9 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
                break;
 
        case XDDP_POOLSZ:
-               if (sopt.optlen != sizeof(len))
-                       return -EINVAL;
-               if (rtipc_get_arg(fd, &len,
-                                 sopt.optval, sizeof(len)))
-                       return -EFAULT;
+               ret = rtipc_get_length(fd, &len, sopt.optval, sopt.optlen);
+               if (ret)
+                       return ret;
                if (len == 0)
                        return -EINVAL;
                cobalt_atomic_enter(s);
@@ -935,8 +923,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
                        return -EPERM;
                if (sopt.optlen != sizeof(monitor))
                        return -EINVAL;
-               if (rtipc_get_arg(NULL, &monitor,
-                                 sopt.optval, sizeof(monitor)))
+               if (rtipc_get_arg(NULL, &monitor, sopt.optval, sizeof(monitor)))
                        return -EFAULT;
                sk->monitor = monitor;
                break;
@@ -944,8 +931,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
        case XDDP_LABEL:
                if (sopt.optlen < sizeof(plabel))
                        return -EINVAL;
-               if (rtipc_get_arg(fd, &plabel,
-                                 sopt.optval, sizeof(plabel)))
+               if (rtipc_get_arg(fd, &plabel, sopt.optval, sizeof(plabel)))
                        return -EFAULT;
                cobalt_atomic_enter(s);
                if (test_bit(_XDDP_BOUND, &sk->status) ||
@@ -974,10 +960,11 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
        struct timeval tv;
        rtdm_lockctx_t s;
        socklen_t len;
-       int ret = 0;
+       int ret;
 
-       if (rtipc_get_arg(fd, &sopt, arg, sizeof(sopt)))
-               return -EFAULT;
+       ret = rtipc_get_sockoptout(fd, &sopt, arg);
+       if (ret)
+               return ret;
 
        if (rtipc_get_arg(fd, &len, sopt.optlen, sizeof(len)))
                return -EFAULT;
@@ -986,12 +973,10 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
                switch (sopt.optname) {
 
                case SO_RCVTIMEO:
-                       if (len != sizeof(tv))
-                               return -EINVAL;
                        rtipc_ns_to_timeval(&tv, sk->timeout);
-                       if (rtipc_put_arg(fd, sopt.optval,
-                                         &tv, sizeof(tv)))
-                               return -EFAULT;
+                       ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
+                       if (ret)
+                               return ret;
                        break;
 
                default:
@@ -1012,8 +997,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
                cobalt_atomic_enter(s);
                strcpy(plabel.label, sk->label);
                cobalt_atomic_leave(s);
-               if (rtipc_put_arg(fd, sopt.optval,
-                                 &plabel, sizeof(plabel)))
+               if (rtipc_put_arg(fd, sopt.optval, &plabel, sizeof(plabel)))
                        return -EFAULT;
                break;
 
@@ -1034,14 +1018,14 @@ static int __xddp_ioctl(struct rtdm_fd *fd,
 
        switch (request) {
 
-       case _RTIOC_CONNECT:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_CONNECT):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret == 0)
                        ret = __xddp_connect_socket(sk, saddrp);
                break;
 
-       case _RTIOC_BIND:
-               ret = rtipc_get_sockaddr(fd, arg, &saddrp);
+       COMPAT_CASE(_RTIOC_BIND):
+               ret = rtipc_get_sockaddr(fd, &saddrp, arg);
                if (ret)
                        return ret;
                if (saddrp == NULL)
@@ -1049,24 +1033,24 @@ static int __xddp_ioctl(struct rtdm_fd *fd,
                ret = __xddp_bind_socket(priv, saddrp);
                break;
 
-       case _RTIOC_GETSOCKNAME:
+       COMPAT_CASE(_RTIOC_GETSOCKNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->name);
                break;
 
-       case _RTIOC_GETPEERNAME:
+       COMPAT_CASE(_RTIOC_GETPEERNAME):
                ret = rtipc_put_sockaddr(fd, arg, &sk->peer);
                break;
 
-       case _RTIOC_SETSOCKOPT:
+       COMPAT_CASE(_RTIOC_SETSOCKOPT):
                ret = __xddp_setsockopt(sk, fd, arg);
                break;
 
-       case _RTIOC_GETSOCKOPT:
+       COMPAT_CASE(_RTIOC_GETSOCKOPT):
                ret = __xddp_getsockopt(sk, fd, arg);
                break;
 
        case _RTIOC_LISTEN:
-       case _RTIOC_ACCEPT:
+       COMPAT_CASE(_RTIOC_ACCEPT):
                ret = -EOPNOTSUPP;
                break;
 
@@ -1084,10 +1068,17 @@ static int __xddp_ioctl(struct rtdm_fd *fd,
 static int xddp_ioctl(struct rtdm_fd *fd,
                      unsigned int request, void *arg)
 {
-       if (rtdm_in_rt_context() && request == _RTIOC_BIND)
-               return -ENOSYS; /* Try downgrading to NRT */
+       int ret;
+
+       switch (request) {
+       COMPAT_CASE(_RTIOC_BIND):
+               if (rtdm_in_rt_context())
+                       return -ENOSYS; /* Try downgrading to NRT */
+       default:
+               ret = __xddp_ioctl(fd, request, arg);
+       }
 
-       return __xddp_ioctl(fd, request, arg);
+       return ret;
 }
 
 static unsigned int xddp_pollstate(struct rtdm_fd *fd)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to