aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/bluetooth/l2cap.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/bluetooth/l2cap.h')
-rw-r--r--include/net/bluetooth/l2cap.h29
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
598static inline void l2cap_chan_hold(struct l2cap_chan *c)
599{
600 atomic_inc(&c->refcnt);
601}
602
603static inline void l2cap_chan_put(struct l2cap_chan *c)
604{
605 if (atomic_dec_and_test(&c->refcnt))
606 kfree(c);
607}
608
598static inline void l2cap_set_timer(struct l2cap_chan *chan, 609static 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
608static inline void l2cap_clear_timer(struct delayed_work *work) 619static 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
625static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) 638static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
626{ 639{