aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-06-01 17:52:58 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-07-21 13:39:04 -0400
commit6e2b6722abaa3f6042357e11f465488b7c12f94c (patch)
treef3c7b190298f4f779bc35eb680e2306da25e06aa /net/bluetooth/l2cap.c
parentbc1b1f8bee63966649dd5ac7d10d31a6556bf19b (diff)
Bluetooth: Fix bug in l2cap_ertm_send() behavior
This patch makes l2cap_ertm_send() similar to the Send-Data action of the ERTM spec. We shall not check for RemoteBusy or WAIT_F state inside l2cap_ertm_send(). Such checks were causing a bug in the retransmission logic of ERTM and making ERTM stalls until the ACL is dropped. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 108c2f290ac..69f098d9814 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1415,11 +1415,8 @@ static int l2cap_ertm_send(struct sock *sk)
1415 u16 control, fcs; 1415 u16 control, fcs;
1416 int nsent = 0; 1416 int nsent = 0;
1417 1417
1418 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1419 return 0;
1420 1418
1421 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && 1419 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
1422 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
1423 1420
1424 if (pi->remote_max_tx && 1421 if (pi->remote_max_tx &&
1425 bt_cb(skb)->retries == pi->remote_max_tx) { 1422 bt_cb(skb)->retries == pi->remote_max_tx) {
@@ -1792,6 +1789,11 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
1792 if (pi->mode == L2CAP_MODE_STREAMING) { 1789 if (pi->mode == L2CAP_MODE_STREAMING) {
1793 err = l2cap_streaming_send(sk); 1790 err = l2cap_streaming_send(sk);
1794 } else { 1791 } else {
1792 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1793 pi->conn_state && L2CAP_CONN_WAIT_F) {
1794 err = len;
1795 break;
1796 }
1795 spin_lock_bh(&pi->send_lock); 1797 spin_lock_bh(&pi->send_lock);
1796 err = l2cap_ertm_send(sk); 1798 err = l2cap_ertm_send(sk);
1797 spin_unlock_bh(&pi->send_lock); 1799 spin_unlock_bh(&pi->send_lock);
@@ -3378,8 +3380,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3378 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) 3380 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3379 __mod_retrans_timer(); 3381 __mod_retrans_timer();
3380 3382
3381 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3382
3383 spin_lock_bh(&pi->send_lock); 3383 spin_lock_bh(&pi->send_lock);
3384 l2cap_ertm_send(sk); 3384 l2cap_ertm_send(sk);
3385 spin_unlock_bh(&pi->send_lock); 3385 spin_unlock_bh(&pi->send_lock);