diff options
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r-- | net/bluetooth/sco.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d919d1161ab4..9e62102443dc 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -83,7 +83,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) | |||
83 | if (conn) | 83 | if (conn) |
84 | return conn; | 84 | return conn; |
85 | 85 | ||
86 | conn = kzalloc(sizeof(struct sco_conn), GFP_ATOMIC); | 86 | conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); |
87 | if (!conn) | 87 | if (!conn) |
88 | return NULL; | 88 | return NULL; |
89 | 89 | ||
@@ -185,7 +185,7 @@ static int sco_connect(struct sock *sk) | |||
185 | 185 | ||
186 | conn = sco_conn_add(hcon); | 186 | conn = sco_conn_add(hcon); |
187 | if (!conn) { | 187 | if (!conn) { |
188 | hci_conn_put(hcon); | 188 | hci_conn_drop(hcon); |
189 | err = -ENOMEM; | 189 | err = -ENOMEM; |
190 | goto done; | 190 | goto done; |
191 | } | 191 | } |
@@ -353,7 +353,7 @@ static void __sco_sock_close(struct sock *sk) | |||
353 | if (sco_pi(sk)->conn->hcon) { | 353 | if (sco_pi(sk)->conn->hcon) { |
354 | sk->sk_state = BT_DISCONN; | 354 | sk->sk_state = BT_DISCONN; |
355 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | 355 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); |
356 | hci_conn_put(sco_pi(sk)->conn->hcon); | 356 | hci_conn_drop(sco_pi(sk)->conn->hcon); |
357 | sco_pi(sk)->conn->hcon = NULL; | 357 | sco_pi(sk)->conn->hcon = NULL; |
358 | } else | 358 | } else |
359 | sco_chan_del(sk, ECONNRESET); | 359 | sco_chan_del(sk, ECONNRESET); |
@@ -481,8 +481,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen | |||
481 | { | 481 | { |
482 | struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; | 482 | struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; |
483 | struct sock *sk = sock->sk; | 483 | struct sock *sk = sock->sk; |
484 | int err = 0; | 484 | int err; |
485 | |||
486 | 485 | ||
487 | BT_DBG("sk %p", sk); | 486 | BT_DBG("sk %p", sk); |
488 | 487 | ||
@@ -653,6 +652,42 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
653 | return err; | 652 | return err; |
654 | } | 653 | } |
655 | 654 | ||
655 | static void sco_conn_defer_accept(struct hci_conn *conn, int mask) | ||
656 | { | ||
657 | struct hci_dev *hdev = conn->hdev; | ||
658 | |||
659 | BT_DBG("conn %p", conn); | ||
660 | |||
661 | conn->state = BT_CONFIG; | ||
662 | |||
663 | if (!lmp_esco_capable(hdev)) { | ||
664 | struct hci_cp_accept_conn_req cp; | ||
665 | |||
666 | bacpy(&cp.bdaddr, &conn->dst); | ||
667 | |||
668 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | ||
669 | cp.role = 0x00; /* Become master */ | ||
670 | else | ||
671 | cp.role = 0x01; /* Remain slave */ | ||
672 | |||
673 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
674 | } else { | ||
675 | struct hci_cp_accept_sync_conn_req cp; | ||
676 | |||
677 | bacpy(&cp.bdaddr, &conn->dst); | ||
678 | cp.pkt_type = cpu_to_le16(conn->pkt_type); | ||
679 | |||
680 | cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
681 | cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
682 | cp.max_latency = __constant_cpu_to_le16(0xffff); | ||
683 | cp.content_format = cpu_to_le16(hdev->voice_setting); | ||
684 | cp.retrans_effort = 0xff; | ||
685 | |||
686 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, | ||
687 | sizeof(cp), &cp); | ||
688 | } | ||
689 | } | ||
690 | |||
656 | static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | 691 | static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
657 | struct msghdr *msg, size_t len, int flags) | 692 | struct msghdr *msg, size_t len, int flags) |
658 | { | 693 | { |
@@ -663,7 +698,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
663 | 698 | ||
664 | if (sk->sk_state == BT_CONNECT2 && | 699 | if (sk->sk_state == BT_CONNECT2 && |
665 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { | 700 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
666 | hci_conn_accept(pi->conn->hcon, 0); | 701 | sco_conn_defer_accept(pi->conn->hcon, 0); |
667 | sk->sk_state = BT_CONFIG; | 702 | sk->sk_state = BT_CONFIG; |
668 | 703 | ||
669 | release_sock(sk); | 704 | release_sock(sk); |
@@ -882,7 +917,7 @@ static void sco_chan_del(struct sock *sk, int err) | |||
882 | sco_conn_unlock(conn); | 917 | sco_conn_unlock(conn); |
883 | 918 | ||
884 | if (conn->hcon) | 919 | if (conn->hcon) |
885 | hci_conn_put(conn->hcon); | 920 | hci_conn_drop(conn->hcon); |
886 | } | 921 | } |
887 | 922 | ||
888 | sk->sk_state = BT_CLOSED; | 923 | sk->sk_state = BT_CLOSED; |