diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-06-01 18:52:58 -0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-07-21 10:39:04 -0700 |
commit | 6e2b6722abaa3f6042357e11f465488b7c12f94c (patch) | |
tree | f3c7b190298f4f779bc35eb680e2306da25e06aa /net/bluetooth | |
parent | bc1b1f8bee63966649dd5ac7d10d31a6556bf19b (diff) | |
download | linux-6e2b6722abaa3f6042357e11f465488b7c12f94c.tar.bz2 |
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')
-rw-r--r-- | net/bluetooth/l2cap.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 108c2f290ac5..69f098d98141 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1415,11 +1415,8 @@ static int l2cap_ertm_send(struct sock *sk) u16 control, fcs; int nsent = 0; - if (pi->conn_state & L2CAP_CONN_WAIT_F) - return 0; - while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && - !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { + while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { if (pi->remote_max_tx && 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 if (pi->mode == L2CAP_MODE_STREAMING) { err = l2cap_streaming_send(sk); } else { + if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && + pi->conn_state && L2CAP_CONN_WAIT_F) { + err = len; + break; + } spin_lock_bh(&pi->send_lock); err = l2cap_ertm_send(sk); spin_unlock_bh(&pi->send_lock); @@ -3378,8 +3380,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) __mod_retrans_timer(); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - spin_lock_bh(&pi->send_lock); l2cap_ertm_send(sk); spin_unlock_bh(&pi->send_lock); |