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.h50
1 files changed, 18 insertions, 32 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ead99f032f7a..d1bb342d083f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -28,6 +28,7 @@
#define __L2CAP_H
#include <asm/unaligned.h>
+#include <linux/atomic.h>
/* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672
@@ -140,6 +141,7 @@ struct l2cap_conninfo {
#define L2CAP_FC_ATT 0x10
#define L2CAP_FC_SIG_LE 0x20
#define L2CAP_FC_SMP_LE 0x40
+#define L2CAP_FC_SMP_BREDR 0x80
/* L2CAP Control Field bit masks */
#define L2CAP_CTRL_SAR 0xC000
@@ -254,6 +256,7 @@ struct l2cap_conn_rsp {
#define L2CAP_CID_ATT 0x0004
#define L2CAP_CID_LE_SIGNALING 0x0005
#define L2CAP_CID_SMP 0x0006
+#define L2CAP_CID_SMP_BREDR 0x0007
#define L2CAP_CID_DYN_START 0x0040
#define L2CAP_CID_DYN_END 0xffff
#define L2CAP_CID_LE_DYN_END 0x007f
@@ -481,6 +484,7 @@ struct l2cap_chan {
struct hci_conn *hs_hcon;
struct hci_chan *hs_hchan;
struct kref kref;
+ atomic_t nesting;
__u8 state;
@@ -604,10 +608,6 @@ struct l2cap_ops {
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb);
- int (*memcpy_fromiovec) (struct l2cap_chan *chan,
- unsigned char *kdata,
- struct iovec *iov,
- int len);
};
struct l2cap_conn {
@@ -617,8 +617,8 @@ struct l2cap_conn {
unsigned int mtu;
__u32 feat_mask;
- __u8 fixed_chan_mask;
- bool hs_enabled;
+ __u8 remote_fixed_chan;
+ __u8 local_fixed_chan;
__u8 info_state;
__u8 info_ident;
@@ -713,6 +713,17 @@ enum {
FLAG_HOLD_HCI_CONN,
};
+/* Lock nesting levels for L2CAP channels. We need these because lockdep
+ * otherwise considers all channels equal and will e.g. complain about a
+ * connection oriented channel triggering SMP procedures or a listening
+ * channel creating and locking a child channel.
+ */
+enum {
+ L2CAP_NESTING_SMP,
+ L2CAP_NESTING_NORMAL,
+ L2CAP_NESTING_PARENT,
+};
+
enum {
L2CAP_TX_STATE_XMIT,
L2CAP_TX_STATE_WAIT_F,
@@ -778,7 +789,7 @@ void l2cap_chan_put(struct l2cap_chan *c);
static inline void l2cap_chan_lock(struct l2cap_chan *chan)
{
- mutex_lock(&chan->lock);
+ mutex_lock_nested(&chan->lock, atomic_read(&chan->nesting));
}
static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
@@ -890,31 +901,6 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan)
return 0;
}
-static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
- unsigned char *kdata,
- struct iovec *iov,
- int len)
-{
- /* Following is safe since for compiler definitions of kvec and
- * iovec are identical, yielding the same in-core layout and alignment
- */
- struct kvec *vec = (struct kvec *)iov;
-
- while (len > 0) {
- if (vec->iov_len) {
- int copy = min_t(unsigned int, len, vec->iov_len);
- memcpy(kdata, vec->iov_base, copy);
- len -= copy;
- kdata += copy;
- vec->iov_base += copy;
- vec->iov_len -= copy;
- }
- vec++;
- }
-
- return 0;
-}
-
extern bool disable_ertm;
int l2cap_init_sockets(void);