summaryrefslogtreecommitdiffstats
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.h40
1 files changed, 34 insertions, 6 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c0d168adf9b..9572cbd12a7 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -522,7 +522,7 @@ struct l2cap_conn {
__u8 info_state;
__u8 info_ident;
- struct delayed_work info_work;
+ struct delayed_work info_timer;
spinlock_t lock;
@@ -532,7 +532,7 @@ struct l2cap_conn {
__u8 disc_reason;
- struct timer_list security_timer;
+ struct delayed_work security_timer;
struct smp_chan *smp_chan;
struct list_head chan_l;
@@ -595,17 +595,45 @@ enum {
FLAG_EFS_ENABLE,
};
+static inline void l2cap_chan_hold(struct l2cap_chan *c)
+{
+ atomic_inc(&c->refcnt);
+}
+
+static inline void l2cap_chan_put(struct l2cap_chan *c)
+{
+ if (atomic_dec_and_test(&c->refcnt))
+ kfree(c);
+}
+
+static inline void l2cap_set_timer(struct l2cap_chan *chan,
+ struct delayed_work *work, long timeout)
+{
+ BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
+
+ if (!__cancel_delayed_work(work))
+ l2cap_chan_hold(chan);
+ schedule_delayed_work(work, timeout);
+}
+
+static inline void l2cap_clear_timer(struct l2cap_chan *chan,
+ struct delayed_work *work)
+{
+ if (__cancel_delayed_work(work))
+ l2cap_chan_put(chan);
+}
+
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
-#define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer)
+#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
L2CAP_DEFAULT_RETRANS_TO);
-#define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer)
+#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
L2CAP_DEFAULT_MONITOR_TO);
-#define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer)
+#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
L2CAP_DEFAULT_ACK_TO);
-#define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer)
+#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
{