diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 148 |
2 files changed, 1 insertions, 150 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ad957f336ead..a056c2bfeb81 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -185,7 +185,6 @@ struct amp_assoc { | |||
185 | 185 | ||
186 | #define HCI_MAX_PAGES 3 | 186 | #define HCI_MAX_PAGES 3 |
187 | 187 | ||
188 | #define NUM_REASSEMBLY 4 | ||
189 | struct hci_dev { | 188 | struct hci_dev { |
190 | struct list_head list; | 189 | struct list_head list; |
191 | struct mutex lock; | 190 | struct mutex lock; |
@@ -327,7 +326,6 @@ struct hci_dev { | |||
327 | struct sk_buff_head cmd_q; | 326 | struct sk_buff_head cmd_q; |
328 | 327 | ||
329 | struct sk_buff *sent_cmd; | 328 | struct sk_buff *sent_cmd; |
330 | struct sk_buff *reassembly[NUM_REASSEMBLY]; | ||
331 | 329 | ||
332 | struct mutex req_lock; | 330 | struct mutex req_lock; |
333 | wait_queue_head_t req_wait_q; | 331 | wait_queue_head_t req_wait_q; |
@@ -1012,7 +1010,6 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
1012 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | 1010 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); |
1013 | 1011 | ||
1014 | int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); | 1012 | int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); |
1015 | int hci_recv_stream_fragment(struct hci_dev *hdev, const void *data, int count); | ||
1016 | 1013 | ||
1017 | void hci_init_sysfs(struct hci_dev *hdev); | 1014 | void hci_init_sysfs(struct hci_dev *hdev); |
1018 | void hci_conn_init_sysfs(struct hci_conn *conn); | 1015 | void hci_conn_init_sysfs(struct hci_conn *conn); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c9e7cafb245a..476709bd068a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -3200,7 +3200,7 @@ EXPORT_SYMBOL(hci_register_dev); | |||
3200 | /* Unregister HCI device */ | 3200 | /* Unregister HCI device */ |
3201 | void hci_unregister_dev(struct hci_dev *hdev) | 3201 | void hci_unregister_dev(struct hci_dev *hdev) |
3202 | { | 3202 | { |
3203 | int i, id; | 3203 | int id; |
3204 | 3204 | ||
3205 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 3205 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
3206 | 3206 | ||
@@ -3214,9 +3214,6 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
3214 | 3214 | ||
3215 | hci_dev_do_close(hdev); | 3215 | hci_dev_do_close(hdev); |
3216 | 3216 | ||
3217 | for (i = 0; i < NUM_REASSEMBLY; i++) | ||
3218 | kfree_skb(hdev->reassembly[i]); | ||
3219 | |||
3220 | cancel_work_sync(&hdev->power_on); | 3217 | cancel_work_sync(&hdev->power_on); |
3221 | 3218 | ||
3222 | if (!test_bit(HCI_INIT, &hdev->flags) && | 3219 | if (!test_bit(HCI_INIT, &hdev->flags) && |
@@ -3320,149 +3317,6 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
3320 | } | 3317 | } |
3321 | EXPORT_SYMBOL(hci_recv_frame); | 3318 | EXPORT_SYMBOL(hci_recv_frame); |
3322 | 3319 | ||
3323 | static int hci_reassembly(struct hci_dev *hdev, int type, const void *data, | ||
3324 | int count, __u8 index) | ||
3325 | { | ||
3326 | int len = 0; | ||
3327 | int hlen = 0; | ||
3328 | int remain = count; | ||
3329 | struct sk_buff *skb; | ||
3330 | struct bt_skb_cb *scb; | ||
3331 | |||
3332 | if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || | ||
3333 | index >= NUM_REASSEMBLY) | ||
3334 | return -EILSEQ; | ||
3335 | |||
3336 | skb = hdev->reassembly[index]; | ||
3337 | |||
3338 | if (!skb) { | ||
3339 | switch (type) { | ||
3340 | case HCI_ACLDATA_PKT: | ||
3341 | len = HCI_MAX_FRAME_SIZE; | ||
3342 | hlen = HCI_ACL_HDR_SIZE; | ||
3343 | break; | ||
3344 | case HCI_EVENT_PKT: | ||
3345 | len = HCI_MAX_EVENT_SIZE; | ||
3346 | hlen = HCI_EVENT_HDR_SIZE; | ||
3347 | break; | ||
3348 | case HCI_SCODATA_PKT: | ||
3349 | len = HCI_MAX_SCO_SIZE; | ||
3350 | hlen = HCI_SCO_HDR_SIZE; | ||
3351 | break; | ||
3352 | } | ||
3353 | |||
3354 | skb = bt_skb_alloc(len, GFP_ATOMIC); | ||
3355 | if (!skb) | ||
3356 | return -ENOMEM; | ||
3357 | |||
3358 | scb = (void *) skb->cb; | ||
3359 | scb->expect = hlen; | ||
3360 | scb->pkt_type = type; | ||
3361 | |||
3362 | hdev->reassembly[index] = skb; | ||
3363 | } | ||
3364 | |||
3365 | while (count) { | ||
3366 | scb = (void *) skb->cb; | ||
3367 | len = min_t(uint, scb->expect, count); | ||
3368 | |||
3369 | memcpy(skb_put(skb, len), data, len); | ||
3370 | |||
3371 | count -= len; | ||
3372 | data += len; | ||
3373 | scb->expect -= len; | ||
3374 | remain = count; | ||
3375 | |||
3376 | switch (type) { | ||
3377 | case HCI_EVENT_PKT: | ||
3378 | if (skb->len == HCI_EVENT_HDR_SIZE) { | ||
3379 | struct hci_event_hdr *h = hci_event_hdr(skb); | ||
3380 | scb->expect = h->plen; | ||
3381 | |||
3382 | if (skb_tailroom(skb) < scb->expect) { | ||
3383 | kfree_skb(skb); | ||
3384 | hdev->reassembly[index] = NULL; | ||
3385 | return -ENOMEM; | ||
3386 | } | ||
3387 | } | ||
3388 | break; | ||
3389 | |||
3390 | case HCI_ACLDATA_PKT: | ||
3391 | if (skb->len == HCI_ACL_HDR_SIZE) { | ||
3392 | struct hci_acl_hdr *h = hci_acl_hdr(skb); | ||
3393 | scb->expect = __le16_to_cpu(h->dlen); | ||
3394 | |||
3395 | if (skb_tailroom(skb) < scb->expect) { | ||
3396 | kfree_skb(skb); | ||
3397 | hdev->reassembly[index] = NULL; | ||
3398 | return -ENOMEM; | ||
3399 | } | ||
3400 | } | ||
3401 | break; | ||
3402 | |||
3403 | case HCI_SCODATA_PKT: | ||
3404 | if (skb->len == HCI_SCO_HDR_SIZE) { | ||
3405 | struct hci_sco_hdr *h = hci_sco_hdr(skb); | ||
3406 | scb->expect = h->dlen; | ||
3407 | |||
3408 | if (skb_tailroom(skb) < scb->expect) { | ||
3409 | kfree_skb(skb); | ||
3410 | hdev->reassembly[index] = NULL; | ||
3411 | return -ENOMEM; | ||
3412 | } | ||
3413 | } | ||
3414 | break; | ||
3415 | } | ||
3416 | |||
3417 | if (scb->expect == 0) { | ||
3418 | /* Complete frame */ | ||
3419 | |||
3420 | bt_cb(skb)->pkt_type = type; | ||
3421 | hci_recv_frame(hdev, skb); | ||
3422 | |||
3423 | hdev->reassembly[index] = NULL; | ||
3424 | return remain; | ||
3425 | } | ||
3426 | } | ||
3427 | |||
3428 | return remain; | ||
3429 | } | ||
3430 | |||
3431 | #define STREAM_REASSEMBLY 0 | ||
3432 | |||
3433 | int hci_recv_stream_fragment(struct hci_dev *hdev, const void *data, int count) | ||
3434 | { | ||
3435 | int type; | ||
3436 | int rem = 0; | ||
3437 | |||
3438 | while (count) { | ||
3439 | struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; | ||
3440 | |||
3441 | if (!skb) { | ||
3442 | const struct { char type; } *pkt; | ||
3443 | |||
3444 | /* Start of the frame */ | ||
3445 | pkt = data; | ||
3446 | type = pkt->type; | ||
3447 | |||
3448 | data++; | ||
3449 | count--; | ||
3450 | } else | ||
3451 | type = bt_cb(skb)->pkt_type; | ||
3452 | |||
3453 | rem = hci_reassembly(hdev, type, data, count, | ||
3454 | STREAM_REASSEMBLY); | ||
3455 | if (rem < 0) | ||
3456 | return rem; | ||
3457 | |||
3458 | data += (count - rem); | ||
3459 | count = rem; | ||
3460 | } | ||
3461 | |||
3462 | return rem; | ||
3463 | } | ||
3464 | EXPORT_SYMBOL(hci_recv_stream_fragment); | ||
3465 | |||
3466 | /* ---- Interface to upper protocols ---- */ | 3320 | /* ---- Interface to upper protocols ---- */ |
3467 | 3321 | ||
3468 | int hci_register_cb(struct hci_cb *cb) | 3322 | int hci_register_cb(struct hci_cb *cb) |