diff options
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
| -rw-r--r-- | net/bluetooth/l2cap_sock.c | 53 | 
1 files changed, 33 insertions, 20 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index e1378693cc90..1884f72083c2 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -279,7 +279,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)  			break;  		/* fall through */  	default: -		err = -ENOTSUPP; +		err = -EOPNOTSUPP;  		goto done;  	} @@ -361,7 +361,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,  	BT_DBG("sock %p, sk %p", sock, sk);  	if (peer && sk->sk_state != BT_CONNECTED && -	    sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2) +	    sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 && +	    sk->sk_state != BT_CONFIG)  		return -ENOTCONN;  	memset(la, 0, sizeof(struct sockaddr_l2)); @@ -796,7 +797,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,  		} else if ((sk->sk_state == BT_CONNECT2 &&  			    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||  			   sk->sk_state == BT_CONNECTED) { -			if (!l2cap_chan_check_security(chan)) +			if (!l2cap_chan_check_security(chan, true))  				set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);  			else  				sk->sk_state_change(sk); @@ -964,7 +965,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock,  		return err;  	l2cap_chan_lock(chan); -	err = l2cap_chan_send(chan, msg, len, sk->sk_priority); +	err = l2cap_chan_send(chan, msg, len);  	l2cap_chan_unlock(chan);  	return err; @@ -1111,7 +1112,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)  		l2cap_chan_close(chan, 0);  		lock_sock(sk); -		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) +		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && +		    !(current->flags & PF_EXITING))  			err = bt_sock_wait_state(sk, BT_CLOSED,  						 sk->sk_lingertime);  	} @@ -1292,6 +1294,7 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,  }  static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, +					       unsigned long hdr_len,  					       unsigned long len, int nb)  {  	struct sock *sk = chan->data; @@ -1299,17 +1302,26 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,  	int err;  	l2cap_chan_unlock(chan); -	skb = bt_skb_send_alloc(sk, len, nb, &err); +	skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);  	l2cap_chan_lock(chan);  	if (!skb)  		return ERR_PTR(err); +	skb->priority = sk->sk_priority; +  	bt_cb(skb)->chan = chan;  	return skb;  } +static int l2cap_sock_memcpy_fromiovec_cb(struct l2cap_chan *chan, +					  unsigned char *kdata, +					  struct iovec *iov, int len) +{ +	return memcpy_fromiovec(kdata, iov, len); +} +  static void l2cap_sock_ready_cb(struct l2cap_chan *chan)  {  	struct sock *sk = chan->data; @@ -1375,20 +1387,21 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)  	sk->sk_state_change(sk);  } -static struct l2cap_ops l2cap_chan_ops = { -	.name		= "L2CAP Socket Interface", -	.new_connection	= l2cap_sock_new_connection_cb, -	.recv		= l2cap_sock_recv_cb, -	.close		= l2cap_sock_close_cb, -	.teardown	= l2cap_sock_teardown_cb, -	.state_change	= l2cap_sock_state_change_cb, -	.ready		= l2cap_sock_ready_cb, -	.defer		= l2cap_sock_defer_cb, -	.resume		= l2cap_sock_resume_cb, -	.suspend	= l2cap_sock_suspend_cb, -	.set_shutdown	= l2cap_sock_set_shutdown_cb, -	.get_sndtimeo	= l2cap_sock_get_sndtimeo_cb, -	.alloc_skb	= l2cap_sock_alloc_skb_cb, +static const struct l2cap_ops l2cap_chan_ops = { +	.name			= "L2CAP Socket Interface", +	.new_connection		= l2cap_sock_new_connection_cb, +	.recv			= l2cap_sock_recv_cb, +	.close			= l2cap_sock_close_cb, +	.teardown		= l2cap_sock_teardown_cb, +	.state_change		= l2cap_sock_state_change_cb, +	.ready			= l2cap_sock_ready_cb, +	.defer			= l2cap_sock_defer_cb, +	.resume			= l2cap_sock_resume_cb, +	.suspend		= l2cap_sock_suspend_cb, +	.set_shutdown		= l2cap_sock_set_shutdown_cb, +	.get_sndtimeo		= l2cap_sock_get_sndtimeo_cb, +	.alloc_skb		= l2cap_sock_alloc_skb_cb, +	.memcpy_fromiovec	= l2cap_sock_memcpy_fromiovec_cb,  };  static void l2cap_sock_destruct(struct sock *sk)  |