diff options
-rw-r--r-- | include/net/bluetooth/l2cap.h | 29 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 29 |
2 files changed, 30 insertions, 28 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index f141fbecfa40..9572cbd12a7a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -595,32 +595,45 @@ enum { | |||
595 | FLAG_EFS_ENABLE, | 595 | FLAG_EFS_ENABLE, |
596 | }; | 596 | }; |
597 | 597 | ||
598 | static inline void l2cap_chan_hold(struct l2cap_chan *c) | ||
599 | { | ||
600 | atomic_inc(&c->refcnt); | ||
601 | } | ||
602 | |||
603 | static inline void l2cap_chan_put(struct l2cap_chan *c) | ||
604 | { | ||
605 | if (atomic_dec_and_test(&c->refcnt)) | ||
606 | kfree(c); | ||
607 | } | ||
608 | |||
598 | static inline void l2cap_set_timer(struct l2cap_chan *chan, | 609 | static inline void l2cap_set_timer(struct l2cap_chan *chan, |
599 | struct delayed_work *work, long timeout) | 610 | struct delayed_work *work, long timeout) |
600 | { | 611 | { |
601 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); | 612 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); |
602 | 613 | ||
603 | cancel_delayed_work_sync(work); | 614 | if (!__cancel_delayed_work(work)) |
604 | 615 | l2cap_chan_hold(chan); | |
605 | schedule_delayed_work(work, timeout); | 616 | schedule_delayed_work(work, timeout); |
606 | } | 617 | } |
607 | 618 | ||
608 | static inline void l2cap_clear_timer(struct delayed_work *work) | 619 | static inline void l2cap_clear_timer(struct l2cap_chan *chan, |
620 | struct delayed_work *work) | ||
609 | { | 621 | { |
610 | cancel_delayed_work_sync(work); | 622 | if (__cancel_delayed_work(work)) |
623 | l2cap_chan_put(chan); | ||
611 | } | 624 | } |
612 | 625 | ||
613 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) | 626 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
614 | #define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer) | 627 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
615 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ | 628 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ |
616 | L2CAP_DEFAULT_RETRANS_TO); | 629 | L2CAP_DEFAULT_RETRANS_TO); |
617 | #define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer) | 630 | #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) |
618 | #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ | 631 | #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ |
619 | L2CAP_DEFAULT_MONITOR_TO); | 632 | L2CAP_DEFAULT_MONITOR_TO); |
620 | #define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer) | 633 | #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) |
621 | #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ | 634 | #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ |
622 | L2CAP_DEFAULT_ACK_TO); | 635 | L2CAP_DEFAULT_ACK_TO); |
623 | #define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer) | 636 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) |
624 | 637 | ||
625 | static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) | 638 | static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) |
626 | { | 639 | { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 173218345a10..944c18913ca0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -77,17 +77,6 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | |||
77 | 77 | ||
78 | /* ---- L2CAP channels ---- */ | 78 | /* ---- L2CAP channels ---- */ |
79 | 79 | ||
80 | static inline void chan_hold(struct l2cap_chan *c) | ||
81 | { | ||
82 | atomic_inc(&c->refcnt); | ||
83 | } | ||
84 | |||
85 | static inline void chan_put(struct l2cap_chan *c) | ||
86 | { | ||
87 | if (atomic_dec_and_test(&c->refcnt)) | ||
88 | kfree(c); | ||
89 | } | ||
90 | |||
91 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) | 80 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) |
92 | { | 81 | { |
93 | struct l2cap_chan *c, *r = NULL; | 82 | struct l2cap_chan *c, *r = NULL; |
@@ -287,7 +276,7 @@ static void l2cap_chan_timeout(struct work_struct *work) | |||
287 | release_sock(sk); | 276 | release_sock(sk); |
288 | 277 | ||
289 | chan->ops->close(chan->data); | 278 | chan->ops->close(chan->data); |
290 | chan_put(chan); | 279 | l2cap_chan_put(chan); |
291 | } | 280 | } |
292 | 281 | ||
293 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) | 282 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) |
@@ -321,7 +310,7 @@ void l2cap_chan_destroy(struct l2cap_chan *chan) | |||
321 | list_del(&chan->global_l); | 310 | list_del(&chan->global_l); |
322 | write_unlock_bh(&chan_list_lock); | 311 | write_unlock_bh(&chan_list_lock); |
323 | 312 | ||
324 | chan_put(chan); | 313 | l2cap_chan_put(chan); |
325 | } | 314 | } |
326 | 315 | ||
327 | static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 316 | static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
@@ -363,7 +352,7 @@ static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
363 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; | 352 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; |
364 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; | 353 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; |
365 | 354 | ||
366 | chan_hold(chan); | 355 | l2cap_chan_hold(chan); |
367 | 356 | ||
368 | list_add_rcu(&chan->list, &conn->chan_l); | 357 | list_add_rcu(&chan->list, &conn->chan_l); |
369 | } | 358 | } |
@@ -385,7 +374,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
385 | list_del_rcu(&chan->list); | 374 | list_del_rcu(&chan->list); |
386 | synchronize_rcu(); | 375 | synchronize_rcu(); |
387 | 376 | ||
388 | chan_put(chan); | 377 | l2cap_chan_put(chan); |
389 | 378 | ||
390 | chan->conn = NULL; | 379 | chan->conn = NULL; |
391 | hci_conn_put(conn->hcon); | 380 | hci_conn_put(conn->hcon); |
@@ -1029,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1029 | hci_chan_del(conn->hchan); | 1018 | hci_chan_del(conn->hchan); |
1030 | 1019 | ||
1031 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1020 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
1032 | cancel_delayed_work_sync(&conn->info_timer); | 1021 | __cancel_delayed_work(&conn->info_timer); |
1033 | 1022 | ||
1034 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { | 1023 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { |
1035 | cancel_delayed_work_sync(&conn->security_timer); | 1024 | __cancel_delayed_work(&conn->security_timer); |
1036 | smp_chan_destroy(conn); | 1025 | smp_chan_destroy(conn); |
1037 | } | 1026 | } |
1038 | 1027 | ||
@@ -2583,7 +2572,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2583 | 2572 | ||
2584 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && | 2573 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && |
2585 | cmd->ident == conn->info_ident) { | 2574 | cmd->ident == conn->info_ident) { |
2586 | cancel_delayed_work_sync(&conn->info_timer); | 2575 | __cancel_delayed_work(&conn->info_timer); |
2587 | 2576 | ||
2588 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 2577 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
2589 | conn->info_ident = 0; | 2578 | conn->info_ident = 0; |
@@ -3129,7 +3118,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
3129 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) | 3118 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) |
3130 | return 0; | 3119 | return 0; |
3131 | 3120 | ||
3132 | cancel_delayed_work_sync(&conn->info_timer); | 3121 | __cancel_delayed_work(&conn->info_timer); |
3133 | 3122 | ||
3134 | if (result != L2CAP_IR_SUCCESS) { | 3123 | if (result != L2CAP_IR_SUCCESS) { |
3135 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 3124 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
@@ -4508,7 +4497,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4508 | 4497 | ||
4509 | if (hcon->type == LE_LINK) { | 4498 | if (hcon->type == LE_LINK) { |
4510 | smp_distribute_keys(conn, 0); | 4499 | smp_distribute_keys(conn, 0); |
4511 | cancel_delayed_work_sync(&conn->security_timer); | 4500 | __cancel_delayed_work(&conn->security_timer); |
4512 | } | 4501 | } |
4513 | 4502 | ||
4514 | rcu_read_lock(); | 4503 | rcu_read_lock(); |