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);
- cancel_delayed_work_sync(work);
-
+ if (!__cancel_delayed_work(work))
+ l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
-static inline void l2cap_clear_timer(struct delayed_work *work)
+static inline void l2cap_clear_timer(struct l2cap_chan *chan,
+ struct delayed_work *work)
{
- cancel_delayed_work_sync(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)
{
/* ---- L2CAP channels ---- */
-static inline void chan_hold(struct l2cap_chan *c)
-{
- atomic_inc(&c->refcnt);
-}
-
-static inline void chan_put(struct l2cap_chan *c)
-{
- if (atomic_dec_and_test(&c->refcnt))
- kfree(c);
-}
-
static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c, *r = NULL;
release_sock(sk);
chan->ops->close(chan->data);
- chan_put(chan);
+ l2cap_chan_put(chan);
}
struct l2cap_chan *l2cap_chan_create(struct sock *sk)
list_del(&chan->global_l);
write_unlock_bh(&chan_list_lock);
- chan_put(chan);
+ l2cap_chan_put(chan);
}
static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
- chan_hold(chan);
+ l2cap_chan_hold(chan);
list_add_rcu(&chan->list, &conn->chan_l);
}
list_del_rcu(&chan->list);
synchronize_rcu();
- chan_put(chan);
+ l2cap_chan_put(chan);
chan->conn = NULL;
hci_conn_put(conn->hcon);
hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
- cancel_delayed_work_sync(&conn->info_timer);
+ __cancel_delayed_work(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
- cancel_delayed_work_sync(&conn->security_timer);
+ __cancel_delayed_work(&conn->security_timer);
smp_chan_destroy(conn);
}
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) {
- cancel_delayed_work_sync(&conn->info_timer);
+ __cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0;
- cancel_delayed_work_sync(&conn->info_timer);
+ __cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0);
- cancel_delayed_work_sync(&conn->security_timer);
+ __cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();