#include <net/sock.h>
 #include <net/tcp.h>
 #include <net/smc.h>
+#include <asm/ioctls.h>
 
 #include "smc.h"
 #include "smc_clc.h"
                     unsigned long arg)
 {
        struct smc_sock *smc;
+       int answ;
 
        smc = smc_sk(sock->sk);
-       if (smc->use_fallback)
+       if (smc->use_fallback) {
+               if (!smc->clcsock)
+                       return -EBADF;
                return smc->clcsock->ops->ioctl(smc->clcsock, cmd, arg);
-       else
-               return sock_no_ioctl(sock, cmd, arg);
+       }
+       switch (cmd) {
+       case SIOCINQ: /* same as FIONREAD */
+               if (smc->sk.sk_state == SMC_LISTEN)
+                       return -EINVAL;
+               answ = atomic_read(&smc->conn.bytes_to_rcv);
+               break;
+       case SIOCOUTQ:
+               /* output queue size (not send + not acked) */
+               if (smc->sk.sk_state == SMC_LISTEN)
+                       return -EINVAL;
+               answ = smc->conn.sndbuf_size -
+                                       atomic_read(&smc->conn.sndbuf_space);
+               break;
+       case SIOCOUTQNSD:
+               /* output queue size (not send only) */
+               if (smc->sk.sk_state == SMC_LISTEN)
+                       return -EINVAL;
+               answ = smc_tx_prepared_sends(&smc->conn);
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+
+       return put_user(answ, (int __user *)arg);
 }
 
 static ssize_t smc_sendpage(struct socket *sock, struct page *page,