|
@@ -666,12 +666,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
|
|
|
{
|
|
|
struct sock *sk = sock->sk;
|
|
|
int err = 0;
|
|
|
+ u32 opt;
|
|
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
switch (optname) {
|
|
|
+
|
|
|
+ case BT_DEFER_SETUP:
|
|
|
+ if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
|
|
|
+ err = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (get_user(opt, (u32 __user *) optval)) {
|
|
|
+ err = -EFAULT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (opt)
|
|
|
+ set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
|
|
|
+ else
|
|
|
+ clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
err = -ENOPROTOOPT;
|
|
|
break;
|
|
@@ -753,6 +772,19 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
|
|
|
lock_sock(sk);
|
|
|
|
|
|
switch (optname) {
|
|
|
+
|
|
|
+ case BT_DEFER_SETUP:
|
|
|
+ if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
|
|
|
+ err = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
|
|
|
+ (u32 __user *) optval))
|
|
|
+ err = -EFAULT;
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
err = -ENOPROTOOPT;
|
|
|
break;
|