struct sock *sk = (void *) arg;
u16 control;
+ bh_lock_sock(sk);
if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
return;
control = L2CAP_CTRL_POLL;
control |= L2CAP_SUPER_RCV_READY;
l2cap_send_sframe(l2cap_pi(sk), control);
+ bh_unlock_sock(sk);
}
static void l2cap_retrans_timeout(unsigned long arg)
struct sock *sk = (void *) arg;
u16 control;
+ bh_lock_sock(sk);
l2cap_pi(sk)->retry_count = 1;
__mod_monitor_timer();
control = L2CAP_CTRL_POLL;
control |= L2CAP_SUPER_RCV_READY;
l2cap_send_sframe(l2cap_pi(sk), control);
+ bh_unlock_sock(sk);
}
static void l2cap_drop_acked_frames(struct sock *sk)
if (enable_ertm)
feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
| L2CAP_FEAT_FCS;
- put_unaligned(cpu_to_le32(feat_mask), (__le32 *) rsp->data);
+ put_unaligned_le32(feat_mask, rsp->data);
l2cap_send_cmd(conn, cmd->ident,
L2CAP_INFO_RSP, sizeof(buf), buf);
} else if (type == L2CAP_IT_FIXED_CHAN) {
case L2CAP_SUPER_RCV_READY:
if (rx_control & L2CAP_CTRL_POLL) {
u16 control = L2CAP_CTRL_FINAL;
- control |= L2CAP_SUPER_RCV_READY;
+ control |= L2CAP_SUPER_RCV_READY |
+ (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
l2cap_send_sframe(l2cap_pi(sk), control);
} else if (rx_control & L2CAP_CTRL_FINAL) {
+ pi->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(sk);
+
if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
break;
break;
case L2CAP_CID_CONN_LESS:
- psm = get_unaligned((__le16 *) skb->data);
+ psm = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
l2cap_conless_channel(conn, psm, skb);
break;