diff options
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index d366423c8392..4e59df5f8e05 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
38 | #include <net/sock.h> | 38 | #include <net/sock.h> |
39 | #include <asm/ioctls.h> | ||
39 | 40 | ||
40 | #if defined(CONFIG_KMOD) | 41 | #if defined(CONFIG_KMOD) |
41 | #include <linux/kmod.h> | 42 | #include <linux/kmod.h> |
@@ -48,7 +49,7 @@ | |||
48 | #define BT_DBG(D...) | 49 | #define BT_DBG(D...) |
49 | #endif | 50 | #endif |
50 | 51 | ||
51 | #define VERSION "2.11" | 52 | #define VERSION "2.12" |
52 | 53 | ||
53 | /* Bluetooth sockets */ | 54 | /* Bluetooth sockets */ |
54 | #define BT_MAX_PROTO 8 | 55 | #define BT_MAX_PROTO 8 |
@@ -266,6 +267,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
266 | 267 | ||
267 | skb_reset_transport_header(skb); | 268 | skb_reset_transport_header(skb); |
268 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 269 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
270 | if (err == 0) | ||
271 | sock_recv_timestamp(msg, sk, skb); | ||
269 | 272 | ||
270 | skb_free_datagram(sk, skb); | 273 | skb_free_datagram(sk, skb); |
271 | 274 | ||
@@ -329,6 +332,54 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w | |||
329 | } | 332 | } |
330 | EXPORT_SYMBOL(bt_sock_poll); | 333 | EXPORT_SYMBOL(bt_sock_poll); |
331 | 334 | ||
335 | int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
336 | { | ||
337 | struct sock *sk = sock->sk; | ||
338 | struct sk_buff *skb; | ||
339 | long amount; | ||
340 | int err; | ||
341 | |||
342 | BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); | ||
343 | |||
344 | switch (cmd) { | ||
345 | case TIOCOUTQ: | ||
346 | if (sk->sk_state == BT_LISTEN) | ||
347 | return -EINVAL; | ||
348 | |||
349 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | ||
350 | if (amount < 0) | ||
351 | amount = 0; | ||
352 | err = put_user(amount, (int __user *) arg); | ||
353 | break; | ||
354 | |||
355 | case TIOCINQ: | ||
356 | if (sk->sk_state == BT_LISTEN) | ||
357 | return -EINVAL; | ||
358 | |||
359 | lock_sock(sk); | ||
360 | skb = skb_peek(&sk->sk_receive_queue); | ||
361 | amount = skb ? skb->len : 0; | ||
362 | release_sock(sk); | ||
363 | err = put_user(amount, (int __user *) arg); | ||
364 | break; | ||
365 | |||
366 | case SIOCGSTAMP: | ||
367 | err = sock_get_timestamp(sk, (struct timeval __user *) arg); | ||
368 | break; | ||
369 | |||
370 | case SIOCGSTAMPNS: | ||
371 | err = sock_get_timestampns(sk, (struct timespec __user *) arg); | ||
372 | break; | ||
373 | |||
374 | default: | ||
375 | err = -ENOIOCTLCMD; | ||
376 | break; | ||
377 | } | ||
378 | |||
379 | return err; | ||
380 | } | ||
381 | EXPORT_SYMBOL(bt_sock_ioctl); | ||
382 | |||
332 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | 383 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) |
333 | { | 384 | { |
334 | DECLARE_WAITQUEUE(wait, current); | 385 | DECLARE_WAITQUEUE(wait, current); |