aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r--net/bluetooth/sco.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 51ae0c3e470a..13c27f17192c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -359,20 +359,9 @@ static void sco_sock_kill(struct sock *sk)
359 sock_put(sk); 359 sock_put(sk);
360} 360}
361 361
362/* Close socket. 362static void __sco_sock_close(struct sock *sk)
363 * Must be called on unlocked socket.
364 */
365static void sco_sock_close(struct sock *sk)
366{ 363{
367 struct sco_conn *conn; 364 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
368
369 sco_sock_clear_timer(sk);
370
371 lock_sock(sk);
372
373 conn = sco_pi(sk)->conn;
374
375 BT_DBG("sk %p state %d conn %p socket %p", sk, sk->sk_state, conn, sk->sk_socket);
376 365
377 switch (sk->sk_state) { 366 switch (sk->sk_state) {
378 case BT_LISTEN: 367 case BT_LISTEN:
@@ -390,9 +379,15 @@ static void sco_sock_close(struct sock *sk)
390 sock_set_flag(sk, SOCK_ZAPPED); 379 sock_set_flag(sk, SOCK_ZAPPED);
391 break; 380 break;
392 } 381 }
382}
393 383
384/* Must be called on unlocked socket. */
385static void sco_sock_close(struct sock *sk)
386{
387 sco_sock_clear_timer(sk);
388 lock_sock(sk);
389 __sco_sock_close(sk);
394 release_sock(sk); 390 release_sock(sk);
395
396 sco_sock_kill(sk); 391 sco_sock_kill(sk);
397} 392}
398 393
@@ -748,6 +743,30 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
748 return err; 743 return err;
749} 744}
750 745
746static int sco_sock_shutdown(struct socket *sock, int how)
747{
748 struct sock *sk = sock->sk;
749 int err = 0;
750
751 BT_DBG("sock %p, sk %p", sock, sk);
752
753 if (!sk)
754 return 0;
755
756 lock_sock(sk);
757 if (!sk->sk_shutdown) {
758 sk->sk_shutdown = SHUTDOWN_MASK;
759 sco_sock_clear_timer(sk);
760 __sco_sock_close(sk);
761
762 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
763 err = bt_sock_wait_state(sk, BT_CLOSED,
764 sk->sk_lingertime);
765 }
766 release_sock(sk);
767 return err;
768}
769
751static int sco_sock_release(struct socket *sock) 770static int sco_sock_release(struct socket *sock)
752{ 771{
753 struct sock *sk = sock->sk; 772 struct sock *sk = sock->sk;
@@ -969,7 +988,7 @@ static const struct proto_ops sco_sock_ops = {
969 .ioctl = bt_sock_ioctl, 988 .ioctl = bt_sock_ioctl,
970 .mmap = sock_no_mmap, 989 .mmap = sock_no_mmap,
971 .socketpair = sock_no_socketpair, 990 .socketpair = sock_no_socketpair,
972 .shutdown = sock_no_shutdown, 991 .shutdown = sco_sock_shutdown,
973 .setsockopt = sco_sock_setsockopt, 992 .setsockopt = sco_sock_setsockopt,
974 .getsockopt = sco_sock_getsockopt 993 .getsockopt = sco_sock_getsockopt
975}; 994};