aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/l2cap.h3
-rw-r--r--net/bluetooth/l2cap_core.c27
2 files changed, 30 insertions, 0 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c695083eee2b..85cf40acc47e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -624,6 +624,9 @@ struct l2cap_conn {
624 __u32 rx_len; 624 __u32 rx_len;
625 __u8 tx_ident; 625 __u8 tx_ident;
626 626
627 struct sk_buff_head pending_rx;
628 struct work_struct pending_rx_work;
629
627 __u8 disc_reason; 630 __u8 disc_reason;
628 631
629 struct delayed_work security_timer; 632 struct delayed_work security_timer;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 317a5737daf6..cd534599fbfa 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1550,6 +1550,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
1550 } 1550 }
1551 1551
1552 mutex_unlock(&conn->chan_lock); 1552 mutex_unlock(&conn->chan_lock);
1553
1554 queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
1553} 1555}
1554 1556
1555/* Notify sockets that we cannot guaranty reliability anymore */ 1557/* Notify sockets that we cannot guaranty reliability anymore */
@@ -1675,6 +1677,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
1675 1677
1676 kfree_skb(conn->rx_skb); 1678 kfree_skb(conn->rx_skb);
1677 1679
1680 skb_queue_purge(&conn->pending_rx);
1681 flush_work(&conn->pending_rx_work);
1682
1678 l2cap_unregister_all_users(conn); 1683 l2cap_unregister_all_users(conn);
1679 1684
1680 mutex_lock(&conn->chan_lock); 1685 mutex_lock(&conn->chan_lock);
@@ -6880,9 +6885,16 @@ drop:
6880static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) 6885static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6881{ 6886{
6882 struct l2cap_hdr *lh = (void *) skb->data; 6887 struct l2cap_hdr *lh = (void *) skb->data;
6888 struct hci_conn *hcon = conn->hcon;
6883 u16 cid, len; 6889 u16 cid, len;
6884 __le16 psm; 6890 __le16 psm;
6885 6891
6892 if (hcon->state != BT_CONNECTED) {
6893 BT_DBG("queueing pending rx skb");
6894 skb_queue_tail(&conn->pending_rx, skb);
6895 return;
6896 }
6897
6886 skb_pull(skb, L2CAP_HDR_SIZE); 6898 skb_pull(skb, L2CAP_HDR_SIZE);
6887 cid = __le16_to_cpu(lh->cid); 6899 cid = __le16_to_cpu(lh->cid);
6888 len = __le16_to_cpu(lh->len); 6900 len = __le16_to_cpu(lh->len);
@@ -6928,6 +6940,18 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6928 } 6940 }
6929} 6941}
6930 6942
6943static void process_pending_rx(struct work_struct *work)
6944{
6945 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6946 pending_rx_work);
6947 struct sk_buff *skb;
6948
6949 BT_DBG("");
6950
6951 while ((skb = skb_dequeue(&conn->pending_rx)))
6952 l2cap_recv_frame(conn, skb);
6953}
6954
6931static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) 6955static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6932{ 6956{
6933 struct l2cap_conn *conn = hcon->l2cap_data; 6957 struct l2cap_conn *conn = hcon->l2cap_data;
@@ -6983,6 +7007,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6983 else 7007 else
6984 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); 7008 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
6985 7009
7010 skb_queue_head_init(&conn->pending_rx);
7011 INIT_WORK(&conn->pending_rx_work, process_pending_rx);
7012
6986 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; 7013 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
6987 7014
6988 return conn; 7015 return conn;