aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-10-04 14:06:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-04 14:06:47 -0400
commitd6222fb0d669307a49e2a96aad86c156a9bb9551 (patch)
tree99c821e5823999b99e7fd49fb840d18cbb89b238
parent76ed94be65c8bd80b565865c186dd9f24bb2f23b (diff)
parentc510eae377c773241ff0b6369a8f3581da941a51 (diff)
Merge branch 'master' of git://github.com/padovan/bluetooth-next
-rw-r--r--drivers/bluetooth/btusb.c6
-rw-r--r--include/net/bluetooth/l2cap.h3
-rw-r--r--net/bluetooth/af_bluetooth.c30
-rw-r--r--net/bluetooth/bnep/core.c5
-rw-r--r--net/bluetooth/cmtp/core.c5
-rw-r--r--net/bluetooth/hci_conn.c14
-rw-r--r--net/bluetooth/hci_event.c20
-rw-r--r--net/bluetooth/hidp/core.c10
-rw-r--r--net/bluetooth/l2cap_core.c255
-rw-r--r--net/bluetooth/rfcomm/core.c5
10 files changed, 157 insertions, 196 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9cbac6b445e1..675246a6f7ef 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -60,6 +60,9 @@ static struct usb_device_id btusb_table[] = {
60 /* Generic Bluetooth USB device */ 60 /* Generic Bluetooth USB device */
61 { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, 61 { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
62 62
63 /* Broadcom SoftSailing reporting vendor specific */
64 { USB_DEVICE(0x05ac, 0x21e1) },
65
63 /* Apple MacBookPro 7,1 */ 66 /* Apple MacBookPro 7,1 */
64 { USB_DEVICE(0x05ac, 0x8213) }, 67 { USB_DEVICE(0x05ac, 0x8213) },
65 68
@@ -708,8 +711,7 @@ static int btusb_send_frame(struct sk_buff *skb)
708 break; 711 break;
709 712
710 case HCI_ACLDATA_PKT: 713 case HCI_ACLDATA_PKT:
711 if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 && 714 if (!data->bulk_tx_ep)
712 hdev->conn_hash.le_num < 1))
713 return -ENODEV; 715 return -ENODEV;
714 716
715 urb = usb_alloc_urb(0, GFP_ATOMIC); 717 urb = usb_alloc_urb(0, GFP_ATOMIC);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7f878b9d5642..ab90ae0970a6 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -354,8 +354,8 @@ struct l2cap_chan {
354 __u8 retry_count; 354 __u8 retry_count;
355 __u8 num_acked; 355 __u8 num_acked;
356 __u16 sdu_len; 356 __u16 sdu_len;
357 __u16 partial_sdu_len;
358 struct sk_buff *sdu; 357 struct sk_buff *sdu;
358 struct sk_buff *sdu_last_frag;
359 359
360 __u8 remote_tx_win; 360 __u8 remote_tx_win;
361 __u8 remote_max_tx; 361 __u8 remote_max_tx;
@@ -448,7 +448,6 @@ enum {
448#define L2CAP_CONF_MAX_CONF_RSP 2 448#define L2CAP_CONF_MAX_CONF_RSP 2
449 449
450enum { 450enum {
451 CONN_SAR_SDU,
452 CONN_SREJ_SENT, 451 CONN_SREJ_SENT,
453 CONN_WAIT_F, 452 CONN_WAIT_F,
454 CONN_SREJ_ACT, 453 CONN_SREJ_ACT,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 117e0d161780..062124cd89cf 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -349,7 +349,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
349 } 349 }
350 350
351 chunk = min_t(unsigned int, skb->len, size); 351 chunk = min_t(unsigned int, skb->len, size);
352 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { 352 if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) {
353 skb_queue_head(&sk->sk_receive_queue, skb); 353 skb_queue_head(&sk->sk_receive_queue, skb);
354 if (!copied) 354 if (!copied)
355 copied = -EFAULT; 355 copied = -EFAULT;
@@ -361,7 +361,33 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
361 sock_recv_ts_and_drops(msg, sk, skb); 361 sock_recv_ts_and_drops(msg, sk, skb);
362 362
363 if (!(flags & MSG_PEEK)) { 363 if (!(flags & MSG_PEEK)) {
364 skb_pull(skb, chunk); 364 int skb_len = skb_headlen(skb);
365
366 if (chunk <= skb_len) {
367 __skb_pull(skb, chunk);
368 } else {
369 struct sk_buff *frag;
370
371 __skb_pull(skb, skb_len);
372 chunk -= skb_len;
373
374 skb_walk_frags(skb, frag) {
375 if (chunk <= frag->len) {
376 /* Pulling partial data */
377 skb->len -= chunk;
378 skb->data_len -= chunk;
379 __skb_pull(frag, chunk);
380 break;
381 } else if (frag->len) {
382 /* Pulling all frag data */
383 chunk -= frag->len;
384 skb->len -= frag->len;
385 skb->data_len -= frag->len;
386 __skb_pull(frag, frag->len);
387 }
388 }
389 }
390
365 if (skb->len) { 391 if (skb->len) {
366 skb_queue_head(&sk->sk_receive_queue, skb); 392 skb_queue_head(&sk->sk_receive_queue, skb);
367 break; 393 break;
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index d9edfe8bf9d6..91bcd3a961ec 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -492,7 +492,10 @@ static int bnep_session(void *arg)
492 /* RX */ 492 /* RX */
493 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 493 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
494 skb_orphan(skb); 494 skb_orphan(skb);
495 bnep_rx_frame(s, skb); 495 if (!skb_linearize(skb))
496 bnep_rx_frame(s, skb);
497 else
498 kfree_skb(skb);
496 } 499 }
497 500
498 if (sk->sk_state != BT_CONNECTED) 501 if (sk->sk_state != BT_CONNECTED)
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 521baa4fe835..7d00ddf9e9dc 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -302,7 +302,10 @@ static int cmtp_session(void *arg)
302 302
303 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 303 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
304 skb_orphan(skb); 304 skb_orphan(skb);
305 cmtp_recv_frame(session, skb); 305 if (!skb_linearize(skb))
306 cmtp_recv_frame(session, skb);
307 else
308 kfree_skb(skb);
306 } 309 }
307 310
308 cmtp_process_transmit(session); 311 cmtp_process_transmit(session);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c2df7bf1d374..c1c597e3e198 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -56,15 +56,15 @@ static void hci_le_connect(struct hci_conn *conn)
56 conn->sec_level = BT_SECURITY_LOW; 56 conn->sec_level = BT_SECURITY_LOW;
57 57
58 memset(&cp, 0, sizeof(cp)); 58 memset(&cp, 0, sizeof(cp));
59 cp.scan_interval = cpu_to_le16(0x0004); 59 cp.scan_interval = cpu_to_le16(0x0060);
60 cp.scan_window = cpu_to_le16(0x0004); 60 cp.scan_window = cpu_to_le16(0x0030);
61 bacpy(&cp.peer_addr, &conn->dst); 61 bacpy(&cp.peer_addr, &conn->dst);
62 cp.peer_addr_type = conn->dst_type; 62 cp.peer_addr_type = conn->dst_type;
63 cp.conn_interval_min = cpu_to_le16(0x0008); 63 cp.conn_interval_min = cpu_to_le16(0x0028);
64 cp.conn_interval_max = cpu_to_le16(0x0100); 64 cp.conn_interval_max = cpu_to_le16(0x0038);
65 cp.supervision_timeout = cpu_to_le16(0x0064); 65 cp.supervision_timeout = cpu_to_le16(0x002a);
66 cp.min_ce_len = cpu_to_le16(0x0001); 66 cp.min_ce_len = cpu_to_le16(0x0000);
67 cp.max_ce_len = cpu_to_le16(0x0001); 67 cp.max_ce_len = cpu_to_le16(0x0000);
68 68
69 hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); 69 hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
70} 70}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 35083f2aa2ea..d7d96b6b1f0d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2174,7 +2174,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
2174 hci_dev_lock(hdev); 2174 hci_dev_lock(hdev);
2175 2175
2176 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2176 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2177 if (conn && conn->state == BT_CONNECTED) { 2177 if (!conn)
2178 goto unlock;
2179
2180 if (conn->state == BT_CONNECTED) {
2178 hci_conn_hold(conn); 2181 hci_conn_hold(conn);
2179 conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2182 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2180 hci_conn_put(conn); 2183 hci_conn_put(conn);
@@ -2194,6 +2197,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
2194 mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure); 2197 mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure);
2195 } 2198 }
2196 2199
2200unlock:
2197 hci_dev_unlock(hdev); 2201 hci_dev_unlock(hdev);
2198} 2202}
2199 2203
@@ -2834,19 +2838,17 @@ unlock:
2834static inline void hci_le_adv_report_evt(struct hci_dev *hdev, 2838static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2835 struct sk_buff *skb) 2839 struct sk_buff *skb)
2836{ 2840{
2837 struct hci_ev_le_advertising_info *ev; 2841 u8 num_reports = skb->data[0];
2838 u8 num_reports; 2842 void *ptr = &skb->data[1];
2839
2840 num_reports = skb->data[0];
2841 ev = (void *) &skb->data[1];
2842 2843
2843 hci_dev_lock(hdev); 2844 hci_dev_lock(hdev);
2844 2845
2845 hci_add_adv_entry(hdev, ev); 2846 while (num_reports--) {
2847 struct hci_ev_le_advertising_info *ev = ptr;
2846 2848
2847 while (--num_reports) {
2848 ev = (void *) (ev->data + ev->length + 1);
2849 hci_add_adv_entry(hdev, ev); 2849 hci_add_adv_entry(hdev, ev);
2850
2851 ptr += sizeof(*ev) + ev->length + 1;
2850 } 2852 }
2851 2853
2852 hci_dev_unlock(hdev); 2854 hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index b83979c548b2..075a3e920caf 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -716,12 +716,18 @@ static int hidp_session(void *arg)
716 716
717 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { 717 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
718 skb_orphan(skb); 718 skb_orphan(skb);
719 hidp_recv_ctrl_frame(session, skb); 719 if (!skb_linearize(skb))
720 hidp_recv_ctrl_frame(session, skb);
721 else
722 kfree_skb(skb);
720 } 723 }
721 724
722 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { 725 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
723 skb_orphan(skb); 726 skb_orphan(skb);
724 hidp_recv_intr_frame(session, skb); 727 if (!skb_linearize(skb))
728 hidp_recv_intr_frame(session, skb);
729 else
730 kfree_skb(skb);
725 } 731 }
726 732
727 hidp_process_transmit(session); 733 hidp_process_transmit(session);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 1611b3544bb1..8cd12917733b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1245,7 +1245,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
1245 __clear_retrans_timer(chan); 1245 __clear_retrans_timer(chan);
1246} 1246}
1247 1247
1248void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) 1248static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
1249{ 1249{
1250 struct hci_conn *hcon = chan->conn->hcon; 1250 struct hci_conn *hcon = chan->conn->hcon;
1251 u16 flags; 1251 u16 flags;
@@ -1261,7 +1261,7 @@ void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
1261 hci_send_acl(hcon, skb, flags); 1261 hci_send_acl(hcon, skb, flags);
1262} 1262}
1263 1263
1264void l2cap_streaming_send(struct l2cap_chan *chan) 1264static void l2cap_streaming_send(struct l2cap_chan *chan)
1265{ 1265{
1266 struct sk_buff *skb; 1266 struct sk_buff *skb;
1267 u16 control, fcs; 1267 u16 control, fcs;
@@ -1327,7 +1327,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
1327 l2cap_do_send(chan, tx_skb); 1327 l2cap_do_send(chan, tx_skb);
1328} 1328}
1329 1329
1330int l2cap_ertm_send(struct l2cap_chan *chan) 1330static int l2cap_ertm_send(struct l2cap_chan *chan)
1331{ 1331{
1332 struct sk_buff *skb, *tx_skb; 1332 struct sk_buff *skb, *tx_skb;
1333 u16 control, fcs; 1333 u16 control, fcs;
@@ -1465,7 +1465,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
1465 return sent; 1465 return sent;
1466} 1466}
1467 1467
1468struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) 1468static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
1469{ 1469{
1470 struct sock *sk = chan->sk; 1470 struct sock *sk = chan->sk;
1471 struct l2cap_conn *conn = chan->conn; 1471 struct l2cap_conn *conn = chan->conn;
@@ -1495,7 +1495,7 @@ struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr
1495 return skb; 1495 return skb;
1496} 1496}
1497 1497
1498struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) 1498static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
1499{ 1499{
1500 struct sock *sk = chan->sk; 1500 struct sock *sk = chan->sk;
1501 struct l2cap_conn *conn = chan->conn; 1501 struct l2cap_conn *conn = chan->conn;
@@ -1572,7 +1572,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
1572 return skb; 1572 return skb;
1573} 1573}
1574 1574
1575int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) 1575static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
1576{ 1576{
1577 struct sk_buff *skb; 1577 struct sk_buff *skb;
1578 struct sk_buff_head sar_queue; 1578 struct sk_buff_head sar_queue;
@@ -3128,102 +3128,104 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
3128 return 0; 3128 return 0;
3129} 3129}
3130 3130
3131static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) 3131static void append_skb_frag(struct sk_buff *skb,
3132 struct sk_buff *new_frag, struct sk_buff **last_frag)
3132{ 3133{
3133 struct sk_buff *_skb; 3134 /* skb->len reflects data in skb as well as all fragments
3134 int err; 3135 * skb->data_len reflects only data in fragments
3136 */
3137 if (!skb_has_frag_list(skb))
3138 skb_shinfo(skb)->frag_list = new_frag;
3139
3140 new_frag->next = NULL;
3141
3142 (*last_frag)->next = new_frag;
3143 *last_frag = new_frag;
3144
3145 skb->len += new_frag->len;
3146 skb->data_len += new_frag->len;
3147 skb->truesize += new_frag->truesize;
3148}
3149
3150static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
3151{
3152 int err = -EINVAL;
3135 3153
3136 switch (control & L2CAP_CTRL_SAR) { 3154 switch (control & L2CAP_CTRL_SAR) {
3137 case L2CAP_SDU_UNSEGMENTED: 3155 case L2CAP_SDU_UNSEGMENTED:
3138 if (test_bit(CONN_SAR_SDU, &chan->conn_state)) 3156 if (chan->sdu)
3139 goto drop; 3157 break;
3140 3158
3141 return chan->ops->recv(chan->data, skb); 3159 err = chan->ops->recv(chan->data, skb);
3160 break;
3142 3161
3143 case L2CAP_SDU_START: 3162 case L2CAP_SDU_START:
3144 if (test_bit(CONN_SAR_SDU, &chan->conn_state)) 3163 if (chan->sdu)
3145 goto drop; 3164 break;
3146 3165
3147 chan->sdu_len = get_unaligned_le16(skb->data); 3166 chan->sdu_len = get_unaligned_le16(skb->data);
3167 skb_pull(skb, 2);
3148 3168
3149 if (chan->sdu_len > chan->imtu) 3169 if (chan->sdu_len > chan->imtu) {
3150 goto disconnect; 3170 err = -EMSGSIZE;
3151 3171 break;
3152 chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); 3172 }
3153 if (!chan->sdu)
3154 return -ENOMEM;
3155 3173
3156 /* pull sdu_len bytes only after alloc, because of Local Busy 3174 if (skb->len >= chan->sdu_len)
3157 * condition we have to be sure that this will be executed 3175 break;
3158 * only once, i.e., when alloc does not fail */
3159 skb_pull(skb, 2);
3160 3176
3161 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); 3177 chan->sdu = skb;
3178 chan->sdu_last_frag = skb;
3162 3179
3163 set_bit(CONN_SAR_SDU, &chan->conn_state); 3180 skb = NULL;
3164 chan->partial_sdu_len = skb->len; 3181 err = 0;
3165 break; 3182 break;
3166 3183
3167 case L2CAP_SDU_CONTINUE: 3184 case L2CAP_SDU_CONTINUE:
3168 if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
3169 goto disconnect;
3170
3171 if (!chan->sdu) 3185 if (!chan->sdu)
3172 goto disconnect; 3186 break;
3173 3187
3174 chan->partial_sdu_len += skb->len; 3188 append_skb_frag(chan->sdu, skb,
3175 if (chan->partial_sdu_len > chan->sdu_len) 3189 &chan->sdu_last_frag);
3176 goto drop; 3190 skb = NULL;
3177 3191
3178 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); 3192 if (chan->sdu->len >= chan->sdu_len)
3193 break;
3179 3194
3195 err = 0;
3180 break; 3196 break;
3181 3197
3182 case L2CAP_SDU_END: 3198 case L2CAP_SDU_END:
3183 if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
3184 goto disconnect;
3185
3186 if (!chan->sdu) 3199 if (!chan->sdu)
3187 goto disconnect; 3200 break;
3188
3189 chan->partial_sdu_len += skb->len;
3190
3191 if (chan->partial_sdu_len > chan->imtu)
3192 goto drop;
3193 3201
3194 if (chan->partial_sdu_len != chan->sdu_len) 3202 append_skb_frag(chan->sdu, skb,
3195 goto drop; 3203 &chan->sdu_last_frag);
3204 skb = NULL;
3196 3205
3197 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); 3206 if (chan->sdu->len != chan->sdu_len)
3207 break;
3198 3208
3199 _skb = skb_clone(chan->sdu, GFP_ATOMIC); 3209 err = chan->ops->recv(chan->data, chan->sdu);
3200 if (!_skb) {
3201 return -ENOMEM;
3202 }
3203 3210
3204 err = chan->ops->recv(chan->data, _skb); 3211 if (!err) {
3205 if (err < 0) { 3212 /* Reassembly complete */
3206 kfree_skb(_skb); 3213 chan->sdu = NULL;
3207 return err; 3214 chan->sdu_last_frag = NULL;
3215 chan->sdu_len = 0;
3208 } 3216 }
3209
3210 clear_bit(CONN_SAR_SDU, &chan->conn_state);
3211
3212 kfree_skb(chan->sdu);
3213 break; 3217 break;
3214 } 3218 }
3215 3219
3216 kfree_skb(skb); 3220 if (err) {
3217 return 0; 3221 kfree_skb(skb);
3218 3222 kfree_skb(chan->sdu);
3219drop: 3223 chan->sdu = NULL;
3220 kfree_skb(chan->sdu); 3224 chan->sdu_last_frag = NULL;
3221 chan->sdu = NULL; 3225 chan->sdu_len = 0;
3226 }
3222 3227
3223disconnect: 3228 return err;
3224 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
3225 kfree_skb(skb);
3226 return 0;
3227} 3229}
3228 3230
3229static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) 3231static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
@@ -3277,99 +3279,6 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
3277 } 3279 }
3278} 3280}
3279 3281
3280static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
3281{
3282 struct sk_buff *_skb;
3283 int err = -EINVAL;
3284
3285 /*
3286 * TODO: We have to notify the userland if some data is lost with the
3287 * Streaming Mode.
3288 */
3289
3290 switch (control & L2CAP_CTRL_SAR) {
3291 case L2CAP_SDU_UNSEGMENTED:
3292 if (test_bit(CONN_SAR_SDU, &chan->conn_state)) {
3293 kfree_skb(chan->sdu);
3294 break;
3295 }
3296
3297 err = chan->ops->recv(chan->data, skb);
3298 if (!err)
3299 return 0;
3300
3301 break;
3302
3303 case L2CAP_SDU_START:
3304 if (test_bit(CONN_SAR_SDU, &chan->conn_state)) {
3305 kfree_skb(chan->sdu);
3306 break;
3307 }
3308
3309 chan->sdu_len = get_unaligned_le16(skb->data);
3310 skb_pull(skb, 2);
3311
3312 if (chan->sdu_len > chan->imtu) {
3313 err = -EMSGSIZE;
3314 break;
3315 }
3316
3317 chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
3318 if (!chan->sdu) {
3319 err = -ENOMEM;
3320 break;
3321 }
3322
3323 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
3324
3325 set_bit(CONN_SAR_SDU, &chan->conn_state);
3326 chan->partial_sdu_len = skb->len;
3327 err = 0;
3328 break;
3329
3330 case L2CAP_SDU_CONTINUE:
3331 if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
3332 break;
3333
3334 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
3335
3336 chan->partial_sdu_len += skb->len;
3337 if (chan->partial_sdu_len > chan->sdu_len)
3338 kfree_skb(chan->sdu);
3339 else
3340 err = 0;
3341
3342 break;
3343
3344 case L2CAP_SDU_END:
3345 if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
3346 break;
3347
3348 memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
3349
3350 clear_bit(CONN_SAR_SDU, &chan->conn_state);
3351 chan->partial_sdu_len += skb->len;
3352
3353 if (chan->partial_sdu_len > chan->imtu)
3354 goto drop;
3355
3356 if (chan->partial_sdu_len == chan->sdu_len) {
3357 _skb = skb_clone(chan->sdu, GFP_ATOMIC);
3358 err = chan->ops->recv(chan->data, _skb);
3359 if (err < 0)
3360 kfree_skb(_skb);
3361 }
3362 err = 0;
3363
3364drop:
3365 kfree_skb(chan->sdu);
3366 break;
3367 }
3368
3369 kfree_skb(skb);
3370 return err;
3371}
3372
3373static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) 3282static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
3374{ 3283{
3375 struct sk_buff *skb; 3284 struct sk_buff *skb;
@@ -3384,7 +3293,7 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
3384 3293
3385 skb = skb_dequeue(&chan->srej_q); 3294 skb = skb_dequeue(&chan->srej_q);
3386 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; 3295 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3387 err = l2cap_ertm_reassembly_sdu(chan, skb, control); 3296 err = l2cap_reassemble_sdu(chan, skb, control);
3388 3297
3389 if (err < 0) { 3298 if (err < 0) {
3390 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 3299 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
@@ -3544,7 +3453,7 @@ expected:
3544 return 0; 3453 return 0;
3545 } 3454 }
3546 3455
3547 err = l2cap_ertm_reassembly_sdu(chan, skb, rx_control); 3456 err = l2cap_reassemble_sdu(chan, skb, rx_control);
3548 chan->buffer_seq = (chan->buffer_seq + 1) % 64; 3457 chan->buffer_seq = (chan->buffer_seq + 1) % 64;
3549 if (err < 0) { 3458 if (err < 0) {
3550 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 3459 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
@@ -3860,12 +3769,20 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
3860 3769
3861 tx_seq = __get_txseq(control); 3770 tx_seq = __get_txseq(control);
3862 3771
3863 if (chan->expected_tx_seq == tx_seq) 3772 if (chan->expected_tx_seq != tx_seq) {
3864 chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; 3773 /* Frame(s) missing - must discard partial SDU */
3865 else 3774 kfree_skb(chan->sdu);
3866 chan->expected_tx_seq = (tx_seq + 1) % 64; 3775 chan->sdu = NULL;
3776 chan->sdu_last_frag = NULL;
3777 chan->sdu_len = 0;
3867 3778
3868 l2cap_streaming_reassembly_sdu(chan, skb, control); 3779 /* TODO: Notify userland of missing data */
3780 }
3781
3782 chan->expected_tx_seq = (tx_seq + 1) % 64;
3783
3784 if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE)
3785 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
3869 3786
3870 goto done; 3787 goto done;
3871 3788
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 5ba3f6df665c..38b618c96de6 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1853,7 +1853,10 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s)
1853 /* Get data directly from socket receive queue without copying it. */ 1853 /* Get data directly from socket receive queue without copying it. */
1854 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 1854 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1855 skb_orphan(skb); 1855 skb_orphan(skb);
1856 rfcomm_recv_frame(s, skb); 1856 if (!skb_linearize(skb))
1857 rfcomm_recv_frame(s, skb);
1858 else
1859 kfree_skb(skb);
1857 } 1860 }
1858 1861
1859 if (sk->sk_state == BT_CLOSED) { 1862 if (sk->sk_state == BT_CLOSED) {