diff options
Diffstat (limited to 'include/net/bluetooth/l2cap.h')
-rw-r--r-- | include/net/bluetooth/l2cap.h | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index f141fbecfa4..9572cbd12a7 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 | { |