|
@@ -335,11 +335,34 @@ EXPORT_SYMBOL(bt_sock_poll);
|
|
|
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
|
struct sock *sk = sock->sk;
|
|
|
+ struct sk_buff *skb;
|
|
|
+ long amount;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
|
|
|
|
|
|
switch (cmd) {
|
|
|
+ case TIOCOUTQ:
|
|
|
+ if (sk->sk_state == BT_LISTEN)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
|
|
|
+ if (amount < 0)
|
|
|
+ amount = 0;
|
|
|
+ err = put_user(amount, (int __user *) arg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TIOCINQ:
|
|
|
+ if (sk->sk_state == BT_LISTEN)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ lock_sock(sk);
|
|
|
+ skb = skb_peek(&sk->sk_receive_queue);
|
|
|
+ amount = skb ? skb->len : 0;
|
|
|
+ release_sock(sk);
|
|
|
+ err = put_user(amount, (int __user *) arg);
|
|
|
+ break;
|
|
|
+
|
|
|
case SIOCGSTAMP:
|
|
|
err = sock_get_timestamp(sk, (struct timeval __user *) arg);
|
|
|
break;
|