diff options
Diffstat (limited to 'include/net/bluetooth/l2cap.h')
-rw-r--r-- | include/net/bluetooth/l2cap.h | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index b1664ed884e6..9b242c6bf55b 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -45,11 +45,11 @@ #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF -#define L2CAP_DISC_TIMEOUT (100) -#define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */ -#define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */ -#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ -#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ +#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100) +#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000) +#define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000) +#define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) +#define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) /* L2CAP socket address */ struct sockaddr_l2 { @@ -492,51 +492,56 @@ struct l2cap_chan { struct sk_buff_head srej_q; struct list_head srej_l; - struct list_head list; - struct list_head global_l; + struct list_head list; + struct list_head global_l; - void *data; - struct l2cap_ops *ops; + void *data; + struct l2cap_ops *ops; + struct mutex lock; }; struct l2cap_ops { - char *name; + char *name; struct l2cap_chan *(*new_connection) (void *data); int (*recv) (void *data, struct sk_buff *skb); void (*close) (void *data); void (*state_change) (void *data, int state); + struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, + unsigned long len, int nb, int *err); + }; struct l2cap_conn { - struct hci_conn *hcon; - struct hci_chan *hchan; + struct hci_conn *hcon; + struct hci_chan *hchan; - bdaddr_t *dst; - bdaddr_t *src; + bdaddr_t *dst; + bdaddr_t *src; - unsigned int mtu; + unsigned int mtu; - __u32 feat_mask; + __u32 feat_mask; + __u8 fixed_chan_mask; - __u8 info_state; - __u8 info_ident; + __u8 info_state; + __u8 info_ident; - struct delayed_work info_timer; + struct delayed_work info_timer; - spinlock_t lock; + spinlock_t lock; - struct sk_buff *rx_skb; - __u32 rx_len; - __u8 tx_ident; + struct sk_buff *rx_skb; + __u32 rx_len; + __u8 tx_ident; - __u8 disc_reason; + __u8 disc_reason; - struct delayed_work security_timer; - struct smp_chan *smp_chan; + struct delayed_work security_timer; + struct smp_chan *smp_chan; - struct list_head chan_l; - struct mutex chan_lock; + struct list_head chan_l; + struct mutex chan_lock; }; #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 @@ -551,9 +556,9 @@ struct l2cap_conn { #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) struct l2cap_pinfo { - struct bt_sock bt; + struct bt_sock bt; struct l2cap_chan *chan; - struct sk_buff *rx_busy_skb; + struct sk_buff *rx_busy_skb; }; enum { @@ -606,21 +611,37 @@ static inline void l2cap_chan_put(struct l2cap_chan *c) kfree(c); } +static inline void l2cap_chan_lock(struct l2cap_chan *chan) +{ + mutex_lock(&chan->lock); +} + +static inline void l2cap_chan_unlock(struct l2cap_chan *chan) +{ + mutex_unlock(&chan->lock); +} + 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); + BT_DBG("chan %p state %s timeout %ld", chan, + state_to_string(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, +static inline bool l2cap_clear_timer(struct l2cap_chan *chan, struct delayed_work *work) { - if (cancel_delayed_work(work)) + bool ret; + + ret = cancel_delayed_work(work); + if (ret) l2cap_chan_put(chan); + + return ret; } #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |