diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 41 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 65 |
2 files changed, 87 insertions, 19 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index f7ada4a2cc5d..ea9c7d061046 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3350,21 +3350,21 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c | |||
3350 | } | 3350 | } |
3351 | 3351 | ||
3352 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); | 3352 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); |
3353 | if (err >= 0) { | 3353 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
3354 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | ||
3355 | return err; | ||
3356 | } | ||
3357 | |||
3358 | l2cap_ertm_enter_local_busy(chan); | ||
3359 | |||
3360 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | ||
3361 | __skb_queue_tail(&chan->busy_q, skb); | ||
3362 | |||
3363 | queue_work(_busy_wq, &chan->busy_work); | ||
3364 | 3354 | ||
3365 | return err; | 3355 | return err; |
3366 | } | 3356 | } |
3367 | 3357 | ||
3358 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy) | ||
3359 | { | ||
3360 | if (chan->mode == L2CAP_MODE_ERTM) { | ||
3361 | if (busy) | ||
3362 | l2cap_ertm_enter_local_busy(chan); | ||
3363 | else | ||
3364 | l2cap_ertm_exit_local_busy(chan); | ||
3365 | } | ||
3366 | } | ||
3367 | |||
3368 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3368 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
3369 | { | 3369 | { |
3370 | struct sk_buff *_skb; | 3370 | struct sk_buff *_skb; |
@@ -3463,13 +3463,22 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3463 | struct sk_buff *skb; | 3463 | struct sk_buff *skb; |
3464 | u16 control; | 3464 | u16 control; |
3465 | 3465 | ||
3466 | while ((skb = skb_peek(&chan->srej_q))) { | 3466 | while ((skb = skb_peek(&chan->srej_q)) && |
3467 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | ||
3468 | int err; | ||
3469 | |||
3467 | if (bt_cb(skb)->tx_seq != tx_seq) | 3470 | if (bt_cb(skb)->tx_seq != tx_seq) |
3468 | break; | 3471 | break; |
3469 | 3472 | ||
3470 | skb = skb_dequeue(&chan->srej_q); | 3473 | skb = skb_dequeue(&chan->srej_q); |
3471 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3474 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; |
3472 | l2cap_ertm_reassembly_sdu(chan, skb, control); | 3475 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); |
3476 | |||
3477 | if (err < 0) { | ||
3478 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | ||
3479 | break; | ||
3480 | } | ||
3481 | |||
3473 | chan->buffer_seq_srej = | 3482 | chan->buffer_seq_srej = |
3474 | (chan->buffer_seq_srej + 1) % 64; | 3483 | (chan->buffer_seq_srej + 1) % 64; |
3475 | tx_seq = (tx_seq + 1) % 64; | 3484 | tx_seq = (tx_seq + 1) % 64; |
@@ -3625,8 +3634,10 @@ expected: | |||
3625 | } | 3634 | } |
3626 | 3635 | ||
3627 | err = l2cap_push_rx_skb(chan, skb, rx_control); | 3636 | err = l2cap_push_rx_skb(chan, skb, rx_control); |
3628 | if (err < 0) | 3637 | if (err < 0) { |
3629 | return 0; | 3638 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3639 | return err; | ||
3640 | } | ||
3630 | 3641 | ||
3631 | if (rx_control & L2CAP_CTRL_FINAL) { | 3642 | if (rx_control & L2CAP_CTRL_FINAL) { |
3632 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3643 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 39082d4e77ce..146b614d10ed 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -711,13 +711,15 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
711 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | 711 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) |
712 | { | 712 | { |
713 | struct sock *sk = sock->sk; | 713 | struct sock *sk = sock->sk; |
714 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
715 | int err; | ||
714 | 716 | ||
715 | lock_sock(sk); | 717 | lock_sock(sk); |
716 | 718 | ||
717 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 719 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { |
718 | sk->sk_state = BT_CONFIG; | 720 | sk->sk_state = BT_CONFIG; |
719 | 721 | ||
720 | __l2cap_connect_rsp_defer(l2cap_pi(sk)->chan); | 722 | __l2cap_connect_rsp_defer(pi->chan); |
721 | release_sock(sk); | 723 | release_sock(sk); |
722 | return 0; | 724 | return 0; |
723 | } | 725 | } |
@@ -725,9 +727,37 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
725 | release_sock(sk); | 727 | release_sock(sk); |
726 | 728 | ||
727 | if (sock->type == SOCK_STREAM) | 729 | if (sock->type == SOCK_STREAM) |
728 | return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); | 730 | err = bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); |
731 | else | ||
732 | err = bt_sock_recvmsg(iocb, sock, msg, len, flags); | ||
733 | |||
734 | if (pi->chan->mode != L2CAP_MODE_ERTM) | ||
735 | return err; | ||
736 | |||
737 | /* Attempt to put pending rx data in the socket buffer */ | ||
738 | |||
739 | lock_sock(sk); | ||
740 | |||
741 | if (!test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state)) | ||
742 | goto done; | ||
743 | |||
744 | if (pi->rx_busy_skb) { | ||
745 | if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb)) | ||
746 | pi->rx_busy_skb = NULL; | ||
747 | else | ||
748 | goto done; | ||
749 | } | ||
729 | 750 | ||
730 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | 751 | /* Restore data flow when half of the receive buffer is |
752 | * available. This avoids resending large numbers of | ||
753 | * frames. | ||
754 | */ | ||
755 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1) | ||
756 | l2cap_chan_busy(pi->chan, 0); | ||
757 | |||
758 | done: | ||
759 | release_sock(sk); | ||
760 | return err; | ||
731 | } | 761 | } |
732 | 762 | ||
733 | /* Kill socket (only if zapped and orphan) | 763 | /* Kill socket (only if zapped and orphan) |
@@ -811,9 +841,31 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) | |||
811 | 841 | ||
812 | static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) | 842 | static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) |
813 | { | 843 | { |
844 | int err; | ||
814 | struct sock *sk = data; | 845 | struct sock *sk = data; |
846 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
815 | 847 | ||
816 | return sock_queue_rcv_skb(sk, skb); | 848 | if (pi->rx_busy_skb) |
849 | return -ENOMEM; | ||
850 | |||
851 | err = sock_queue_rcv_skb(sk, skb); | ||
852 | |||
853 | /* For ERTM, handle one skb that doesn't fit into the recv | ||
854 | * buffer. This is important to do because the data frames | ||
855 | * have already been acked, so the skb cannot be discarded. | ||
856 | * | ||
857 | * Notify the l2cap core that the buffer is full, so the | ||
858 | * LOCAL_BUSY state is entered and no more frames are | ||
859 | * acked and reassembled until there is buffer space | ||
860 | * available. | ||
861 | */ | ||
862 | if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) { | ||
863 | pi->rx_busy_skb = skb; | ||
864 | l2cap_chan_busy(pi->chan, 1); | ||
865 | err = 0; | ||
866 | } | ||
867 | |||
868 | return err; | ||
817 | } | 869 | } |
818 | 870 | ||
819 | static void l2cap_sock_close_cb(void *data) | 871 | static void l2cap_sock_close_cb(void *data) |
@@ -842,6 +894,11 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
842 | { | 894 | { |
843 | BT_DBG("sk %p", sk); | 895 | BT_DBG("sk %p", sk); |
844 | 896 | ||
897 | if (l2cap_pi(sk)->rx_busy_skb) { | ||
898 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); | ||
899 | l2cap_pi(sk)->rx_busy_skb = NULL; | ||
900 | } | ||
901 | |||
845 | skb_queue_purge(&sk->sk_receive_queue); | 902 | skb_queue_purge(&sk->sk_receive_queue); |
846 | skb_queue_purge(&sk->sk_write_queue); | 903 | skb_queue_purge(&sk->sk_write_queue); |
847 | } | 904 | } |