* [PATCH 00/15] L2CAP Rewrite (or create proper struct l2cap_chan)
@ 2011-04-01 22:33 Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
This patchset is the very beginning of a series of patches to remove the
socket dependence from the core l2cap operations. The main motivation around
this is to have a clear separation between L2CAP socket operations and L2CAP
channels operations.
By fixing this we will be able to fix the RFCOMM's L2CAP usage, that today is
via the socket calls from inside the kernel. This approach is totally mess
and have been a headache for almost ten years now due to inumerous locking
bugs that we had.
Next step is keep cleaning l2cap_core.c by removing socket references from it.
In short, we will be done, when l2cap_core.c is clean of any socket reference
and we write a API to access L2CAP core from l2cap_sock.c, RFCOMM and in the
future AMP Manager.
These first changes are very simple, hopefully, it's not breaking anything.
But of course I'll test all the changes against PTS, before they reach Linus'
tree. Please review.
Gustavo F. Padovan (15):
Bluetooth: Create struct l2cap_chan
Bluetooth: Use struct list_head for L2CAP channels list
Bluetooth: Remove struct del_list
Bluetooth: Move ident to struct l2cap_chan
Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan
Bluetooth: clean up l2cap_sock_recvmsg()
Bluetooth: Move conn_state to struct l2cap_chan
Bluetooth: Move of ERTM *_seq vars to struct l2cap_chan
Bluetooth: Move more ERTM stuff to struct l2cap_chan
Bluetooth: Move SDU related vars to struct l2cap_chan
Bluetooth: Move remote info to struct l2cap_chan
Bluetooth: Move ERTM timers to struct l2cap_chan
Bluetooth: Move srej and busy queues to struct l2cap_chan
Bluetooth: Move busy workqueue to struct l2cap_chan
Bluetooth: Fix lockdep warning with skb list lock
include/net/bluetooth/l2cap.h | 113 ++--
net/bluetooth/l2cap_core.c | 1226 ++++++++++++++++++++++-------------------
net/bluetooth/l2cap_sock.c | 62 +--
3 files changed, 730 insertions(+), 671 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 01/15] Bluetooth: Create struct l2cap_chan
2011-04-01 22:33 [PATCH 00/15] L2CAP Rewrite (or create proper struct l2cap_chan) Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Gustavo F. Padovan
2011-04-04 19:22 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Anderson Lizardo
0 siblings, 2 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
struct l2cap_chan cames to create a clear separation between what
properties and data belongs to the L2CAP channel and what belongs to the
socket. By now we just fold the struct sock * in struct l2cap_chan as all
the channel info is struct l2cap_pinfo today.
In the next commits we will see a move of channel stuff to struct
l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 18 ++-
net/bluetooth/l2cap_core.c | 247 ++++++++++++++++++++++++++--------------
net/bluetooth/l2cap_sock.c | 6 +-
3 files changed, 175 insertions(+), 96 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 2b9ca0d..6378bcc 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -276,9 +276,16 @@ struct l2cap_conn_param_update_rsp {
#define L2CAP_CONN_PARAM_ACCEPTED 0x0000
#define L2CAP_CONN_PARAM_REJECTED 0x0001
-/* ----- L2CAP connections ----- */
+/* ----- L2CAP channels and connections ----- */
+
+struct l2cap_chan {
+ struct sock *sk;
+ struct l2cap_chan *next_c;
+ struct l2cap_chan *prev_c;
+};
+
struct l2cap_chan_list {
- struct sock *head;
+ struct l2cap_chan *head;
rwlock_t lock;
};
@@ -317,7 +324,7 @@ struct sock_del_list {
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
-/* ----- L2CAP channel and socket info ----- */
+/* ----- L2CAP socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
@@ -389,8 +396,7 @@ struct l2cap_pinfo {
struct work_struct busy_work;
struct srej_list srej_l;
struct l2cap_conn *conn;
- struct sock *next_c;
- struct sock *prev_c;
+ struct l2cap_chan *chan;
};
#define L2CAP_CONF_REQ_SENT 0x01
@@ -471,7 +477,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
-void l2cap_chan_del(struct sock *sk, int err);
+void l2cap_chan_del(struct l2cap_chan *chan, int err);
int l2cap_do_connect(struct sock *sk);
#endif /* __L2CAP_H */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c3cebed..e49d8f7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -74,58 +74,58 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP channels ---- */
-static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->dcid == cid)
+ struct l2cap_chan *c;
+ for (c = l->head; c; c = c->next_c) {
+ if (l2cap_pi(c->sk)->dcid == cid)
break;
}
- return s;
+ return c;
}
-static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->scid == cid)
+ struct l2cap_chan *c;
+ for (c = l->head; c; c = c->next_c) {
+ if (l2cap_pi(c->sk)->scid == cid)
break;
}
- return s;
+ return c;
}
/* Find channel with given SCID.
* Returns locked socket */
-static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static inline struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
{
- struct sock *s;
+ struct l2cap_chan *c;
read_lock(&l->lock);
- s = __l2cap_get_chan_by_scid(l, cid);
- if (s)
- bh_lock_sock(s);
+ c = __l2cap_get_chan_by_scid(l, cid);
+ if (c)
+ bh_lock_sock(c->sk);
read_unlock(&l->lock);
- return s;
+ return c;
}
-static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->ident == ident)
+ struct l2cap_chan *c;
+ for (c = l->head; c; c = c->next_c) {
+ if (l2cap_pi(c->sk)->ident == ident)
break;
}
- return s;
+ return c;
}
-static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
{
- struct sock *s;
+ struct l2cap_chan *c;
read_lock(&l->lock);
- s = __l2cap_get_chan_by_ident(l, ident);
- if (s)
- bh_lock_sock(s);
+ c = __l2cap_get_chan_by_ident(l, ident);
+ if (c)
+ bh_lock_sock(c->sk);
read_unlock(&l->lock);
- return s;
+ return c;
}
static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
@@ -140,38 +140,52 @@ static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
return 0;
}
-static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
+{
+ struct l2cap_chan *chan;
+
+ chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
+ if (!chan)
+ return NULL;
+
+ chan->sk = sk;
+
+ return chan;
+}
+
+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct l2cap_chan *chan)
{
- sock_hold(sk);
+ sock_hold(chan->sk);
if (l->head)
- l2cap_pi(l->head)->prev_c = sk;
+ l->head->prev_c = chan;
- l2cap_pi(sk)->next_c = l->head;
- l2cap_pi(sk)->prev_c = NULL;
- l->head = sk;
+ chan->next_c = l->head;
+ chan->prev_c = NULL;
+ l->head = chan;
}
-static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct l2cap_chan *chan)
{
- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
+ struct l2cap_chan *next = chan->next_c, *prev = chan->prev_c;
write_lock_bh(&l->lock);
- if (sk == l->head)
+ if (chan == l->head)
l->head = next;
if (next)
- l2cap_pi(next)->prev_c = prev;
+ next->prev_c = prev;
if (prev)
- l2cap_pi(prev)->next_c = next;
+ prev->next_c = next;
write_unlock_bh(&l->lock);
- __sock_put(sk);
+ __sock_put(chan->sk);
}
-static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
+static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
struct l2cap_chan_list *l = &conn->chan_list;
+ struct sock *sk = chan->sk;
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
@@ -203,13 +217,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
}
- __l2cap_chan_link(l, sk);
+ __l2cap_chan_link(l, chan);
}
/* Delete channel.
* Must be called on the locked socket. */
-void l2cap_chan_del(struct sock *sk, int err)
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
{
+ struct sock *sk = chan->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct sock *parent = bt_sk(sk)->parent;
@@ -219,7 +234,7 @@ void l2cap_chan_del(struct sock *sk, int err)
if (conn) {
/* Unlink from channel list */
- l2cap_chan_unlink(&conn->chan_list, sk);
+ l2cap_chan_unlink(&conn->chan_list, chan);
l2cap_pi(sk)->conn = NULL;
hci_conn_put(conn->hcon);
}
@@ -253,6 +268,8 @@ void l2cap_chan_del(struct sock *sk, int err)
kfree(l);
}
}
+
+ kfree(chan);
}
static inline u8 l2cap_get_auth_type(struct sock *sk)
@@ -487,7 +504,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
{
struct l2cap_chan_list *l = &conn->chan_list;
struct sock_del_list del, *tmp1, *tmp2;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
@@ -495,7 +512,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ for (chan = l->head; chan; chan = chan->next_c) {
+ struct sock *sk = chan->sk;
bh_lock_sock(sk);
if (sk->sk_type != SOCK_SEQPACKET &&
@@ -622,6 +640,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
struct l2cap_chan_list *list = &conn->chan_list;
struct sock *parent, *uninitialized_var(sk);
+ struct l2cap_chan *chan;
BT_DBG("");
@@ -641,6 +660,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (!sk)
goto clean;
+ chan = l2cap_chan_alloc(sk);
+ if (!chan) {
+ l2cap_sock_kill(sk);
+ goto clean;
+ }
+
write_lock_bh(&list->lock);
hci_conn_hold(conn->hcon);
@@ -651,7 +676,9 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
bt_accept_enqueue(parent, sk);
- __l2cap_chan_add(conn, sk);
+ __l2cap_chan_add(conn, chan);
+
+ l2cap_pi(sk)->chan = chan;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
@@ -667,7 +694,7 @@ clean:
static void l2cap_conn_ready(struct l2cap_conn *conn)
{
struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
@@ -676,7 +703,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ for (chan = l->head; chan; chan = chan->next_c) {
+ struct sock *sk = chan->sk;
bh_lock_sock(sk);
if (conn->hcon->type == LE_LINK) {
@@ -703,13 +731,14 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
{
struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ for (chan = l->head; chan; chan = chan->next_c) {
+ struct sock *sk = chan->sk;
if (l2cap_pi(sk)->force_reliable)
sk->sk_err = err;
}
@@ -768,6 +797,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
static void l2cap_conn_del(struct hci_conn *hcon, int err)
{
struct l2cap_conn *conn = hcon->l2cap_data;
+ struct l2cap_chan *chan;
struct sock *sk;
if (!conn)
@@ -778,9 +808,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree_skb(conn->rx_skb);
/* Kill channels */
- while ((sk = conn->chan_list.head)) {
+ while ((chan = conn->chan_list.head)) {
+ sk = chan->sk;
bh_lock_sock(sk);
- l2cap_chan_del(sk, err);
+ l2cap_chan_del(chan, err);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
}
@@ -792,11 +823,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree(conn);
}
-static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
struct l2cap_chan_list *l = &conn->chan_list;
write_lock_bh(&l->lock);
- __l2cap_chan_add(conn, sk);
+ __l2cap_chan_add(conn, chan);
write_unlock_bh(&l->lock);
}
@@ -837,6 +868,7 @@ int l2cap_do_connect(struct sock *sk)
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
+ struct l2cap_chan *chan;
struct hci_conn *hcon;
struct hci_dev *hdev;
__u8 auth_type;
@@ -872,10 +904,19 @@ int l2cap_do_connect(struct sock *sk)
goto done;
}
+ chan = l2cap_chan_alloc(sk);
+ if (!chan) {
+ hci_conn_put(hcon);
+ err = -ENOMEM;
+ goto done;
+ }
+
/* Update source addr of the socket */
bacpy(src, conn->src);
- l2cap_chan_add(conn, sk);
+ l2cap_chan_add(conn, chan);
+
+ l2cap_pi(sk)->chan = chan;
sk->sk_state = BT_CONNECT;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
@@ -1387,12 +1428,13 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct l2cap_chan_list *l = &conn->chan_list;
struct sk_buff *nskb;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ for (chan = l->head; chan; chan = chan->next_c) {
+ struct sock *sk = chan->sk;
if (sk->sk_type != SOCK_RAW)
continue;
@@ -1976,6 +2018,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
struct l2cap_chan_list *list = &conn->chan_list;
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
+ struct l2cap_chan *chan;
struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
@@ -2013,6 +2056,12 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
if (!sk)
goto response;
+ chan = l2cap_chan_alloc(sk);
+ if (!chan) {
+ l2cap_sock_kill(sk);
+ goto response;
+ }
+
write_lock_bh(&list->lock);
/* Check if we already have channel with that dcid */
@@ -2033,7 +2082,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
bt_accept_enqueue(parent, sk);
- __l2cap_chan_add(conn, sk);
+ __l2cap_chan_add(conn, chan);
+
+ l2cap_pi(sk)->chan = chan;
+
dcid = l2cap_pi(sk)->scid;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
@@ -2105,6 +2157,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
{
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
u16 scid, dcid, result, status;
+ struct l2cap_chan *chan;
struct sock *sk;
u8 req[128];
@@ -2116,15 +2169,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
if (scid) {
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ if (!chan)
return -EFAULT;
} else {
- sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
- if (!sk)
+ chan = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
+ if (!chan)
return -EFAULT;
}
+ sk = chan->sk;
+
switch (result) {
case L2CAP_CR_SUCCESS:
sk->sk_state = BT_CONFIG;
@@ -2155,7 +2210,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break;
}
- l2cap_chan_del(sk, ECONNREFUSED);
+ l2cap_chan_del(chan, ECONNREFUSED);
break;
}
@@ -2179,6 +2234,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
u16 dcid, flags;
u8 rsp[64];
+ struct l2cap_chan *chan;
struct sock *sk;
int len;
@@ -2187,10 +2243,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+ if (!chan)
return -ENOENT;
+ sk = chan->sk;
+
if (sk->sk_state != BT_CONFIG) {
struct l2cap_cmd_rej rej;
@@ -2269,6 +2327,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
{
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
+ struct l2cap_chan *chan;
struct sock *sk;
int len = cmd->len - sizeof(*rsp);
@@ -2279,10 +2338,12 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
scid, flags, result);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ if (!chan)
return 0;
+ sk = chan->sk;
+
switch (result) {
case L2CAP_CONF_SUCCESS:
l2cap_conf_rfc_get(sk, rsp->data, len);
@@ -2349,6 +2410,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
struct l2cap_disconn_rsp rsp;
u16 dcid, scid;
+ struct l2cap_chan *chan;
struct sock *sk;
scid = __le16_to_cpu(req->scid);
@@ -2356,10 +2418,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+ if (!chan)
return 0;
+ sk = chan->sk;
+
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
@@ -2375,7 +2439,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
return 0;
}
- l2cap_chan_del(sk, ECONNRESET);
+ l2cap_chan_del(chan, ECONNRESET);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
@@ -2386,6 +2450,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
{
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
u16 dcid, scid;
+ struct l2cap_chan *chan;
struct sock *sk;
scid = __le16_to_cpu(rsp->scid);
@@ -2393,10 +2458,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ if (!chan)
return 0;
+ sk = chan->sk;
+
/* don't delete l2cap channel if sk is owned by user */
if (sock_owned_by_user(sk)) {
sk->sk_state = BT_DISCONN;
@@ -2406,7 +2473,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
return 0;
}
- l2cap_chan_del(sk, 0);
+ l2cap_chan_del(chan, 0);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
@@ -3538,18 +3605,20 @@ drop:
static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
{
+ struct l2cap_chan *chan;
struct sock *sk;
struct l2cap_pinfo *pi;
u16 control;
u8 tx_seq;
int len;
- sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
- if (!sk) {
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+ if (!chan) {
BT_DBG("unknown cid 0x%4.4x", cid);
goto drop;
}
+ sk = chan->sk;
pi = l2cap_pi(sk);
BT_DBG("sk %p, len %d", sk, skb->len);
@@ -3788,7 +3857,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
{
struct l2cap_chan_list *l;
struct l2cap_conn *conn = hcon->l2cap_data;
- struct sock *sk;
+ struct l2cap_chan *chan;
if (!conn)
return 0;
@@ -3799,7 +3868,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ for (chan = l->head; chan; chan = chan->next_c) {
+ struct sock *sk = chan->sk;
bh_lock_sock(sk);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
@@ -3872,7 +3942,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (!(flags & ACL_CONT)) {
struct l2cap_hdr *hdr;
- struct sock *sk;
+ struct l2cap_chan *chan;
u16 cid;
int len;
@@ -3910,18 +3980,21 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
goto drop;
}
- sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+ chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
- if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
- BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
- len, l2cap_pi(sk)->imtu);
- bh_unlock_sock(sk);
- l2cap_conn_unreliable(conn, ECOMM);
- goto drop;
- }
+ if (chan && chan->sk) {
+ struct sock *sk = chan->sk;
- if (sk)
+ if (l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
+ BT_ERR("Frame exceeding recv MTU (len %d, "
+ "MTU %d)", len,
+ l2cap_pi(sk)->imtu);
+ bh_unlock_sock(sk);
+ l2cap_conn_unreliable(conn, ECOMM);
+ goto drop;
+ }
bh_unlock_sock(sk);
+ }
/* Allocate skb for the complete frame (with header) */
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f77308e..7df8118 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -902,7 +902,7 @@ void __l2cap_sock_close(struct sock *sk, int reason)
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
l2cap_send_disconn_req(conn, sk, reason);
} else
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(l2cap_pi(sk)->chan, reason);
break;
case BT_CONNECT2:
@@ -925,12 +925,12 @@ void __l2cap_sock_close(struct sock *sk, int reason)
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
}
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(l2cap_pi(sk)->chan, reason);
break;
case BT_CONNECT:
case BT_DISCONN:
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(l2cap_pi(sk)->chan, reason);
break;
default:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list
2011-04-01 22:33 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 03/15] Bluetooth: Remove struct del_list Gustavo F. Padovan
2011-04-04 20:28 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Anderson Lizardo
2011-04-04 19:22 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Anderson Lizardo
1 sibling, 2 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
Use a well known Kernel API is always a good idea than implement your own
list.
In the future we might use RCU on this list.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 12 +--
net/bluetooth/l2cap_core.c | 195 +++++++++++++++++++----------------------
2 files changed, 93 insertions(+), 114 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6378bcc..ddf4bc5 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -277,16 +277,9 @@ struct l2cap_conn_param_update_rsp {
#define L2CAP_CONN_PARAM_REJECTED 0x0001
/* ----- L2CAP channels and connections ----- */
-
struct l2cap_chan {
struct sock *sk;
- struct l2cap_chan *next_c;
- struct l2cap_chan *prev_c;
-};
-
-struct l2cap_chan_list {
- struct l2cap_chan *head;
- rwlock_t lock;
+ struct list_head list;
};
struct l2cap_conn {
@@ -312,7 +305,8 @@ struct l2cap_conn {
__u8 disc_reason;
- struct l2cap_chan_list chan_list;
+ struct list_head chan_l;
+ rwlock_t chan_lock;
};
struct sock_del_list {
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e49d8f7..ce68896 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -74,66 +74,75 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP channels ---- */
-static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c;
- for (c = l->head; c; c = c->next_c) {
- if (l2cap_pi(c->sk)->dcid == cid)
- break;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ struct sock *s = c->sk;
+ if (l2cap_pi(s)->dcid == cid)
+ return c;
}
- return c;
+ return NULL;
+
}
-static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c;
- for (c = l->head; c; c = c->next_c) {
- if (l2cap_pi(c->sk)->scid == cid)
- break;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ struct sock *s = c->sk;
+ if (l2cap_pi(s)->scid == cid)
+ return c;
}
- return c;
+ return NULL;
}
/* Find channel with given SCID.
* Returns locked socket */
-static inline struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c;
- read_lock(&l->lock);
- c = __l2cap_get_chan_by_scid(l, cid);
+
+ read_lock(&conn->chan_lock);
+ c = __l2cap_get_chan_by_scid(conn, cid);
if (c)
bh_lock_sock(c->sk);
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
return c;
}
-static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
{
struct l2cap_chan *c;
- for (c = l->head; c; c = c->next_c) {
- if (l2cap_pi(c->sk)->ident == ident)
- break;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ struct sock *s = c->sk;
+ if (l2cap_pi(s)->ident == ident)
+ return c;
}
- return c;
+ return NULL;
}
-static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
{
struct l2cap_chan *c;
- read_lock(&l->lock);
- c = __l2cap_get_chan_by_ident(l, ident);
+
+ read_lock(&conn->chan_lock);
+ c = __l2cap_get_chan_by_ident(conn, ident);
if (c)
bh_lock_sock(c->sk);
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
return c;
}
-static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
+static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
{
u16 cid = L2CAP_CID_DYN_START;
for (; cid < L2CAP_CID_DYN_END; cid++) {
- if (!__l2cap_get_chan_by_scid(l, cid))
+ if (!__l2cap_get_chan_by_scid(conn, cid))
return cid;
}
@@ -153,38 +162,8 @@ static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
return chan;
}
-static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct l2cap_chan *chan)
-{
- sock_hold(chan->sk);
-
- if (l->head)
- l->head->prev_c = chan;
-
- chan->next_c = l->head;
- chan->prev_c = NULL;
- l->head = chan;
-}
-
-static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct l2cap_chan *chan)
-{
- struct l2cap_chan *next = chan->next_c, *prev = chan->prev_c;
-
- write_lock_bh(&l->lock);
- if (chan == l->head)
- l->head = next;
-
- if (next)
- next->prev_c = prev;
- if (prev)
- prev->next_c = next;
- write_unlock_bh(&l->lock);
-
- __sock_put(chan->sk);
-}
-
static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct sock *sk = chan->sk;
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
@@ -202,7 +181,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
} else {
/* Alloc CID for connection-oriented socket */
- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+ l2cap_pi(sk)->scid = l2cap_alloc_cid(conn);
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
}
} else if (sk->sk_type == SOCK_DGRAM) {
@@ -217,7 +196,9 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
}
- __l2cap_chan_link(l, chan);
+ sock_hold(sk);
+
+ list_add(&chan->list, &conn->chan_l);
}
/* Delete channel.
@@ -233,8 +214,12 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
if (conn) {
- /* Unlink from channel list */
- l2cap_chan_unlink(&conn->chan_list, chan);
+ /* Delete from channel list */
+ write_lock_bh(&conn->chan_lock);
+ list_del(&chan->list);
+ write_unlock_bh(&conn->chan_lock);
+ __sock_put(sk);
+
l2cap_pi(sk)->conn = NULL;
hci_conn_put(conn->hcon);
}
@@ -502,7 +487,6 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
/* ---- L2CAP connections ---- */
static void l2cap_conn_start(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct sock_del_list del, *tmp1, *tmp2;
struct l2cap_chan *chan;
@@ -510,10 +494,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
INIT_LIST_HEAD(&del.list);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
- for (chan = l->head; chan; chan = chan->next_c) {
+ list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
+
bh_lock_sock(sk);
if (sk->sk_type != SOCK_SEQPACKET &&
@@ -593,7 +578,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
bh_lock_sock(tmp1->sk);
@@ -638,7 +623,6 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *list = &conn->chan_list;
struct sock *parent, *uninitialized_var(sk);
struct l2cap_chan *chan;
@@ -666,11 +650,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
goto clean;
}
- write_lock_bh(&list->lock);
+ write_lock_bh(&conn->chan_lock);
hci_conn_hold(conn->hcon);
l2cap_sock_init(sk, parent);
+
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
@@ -685,7 +670,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
sk->sk_state = BT_CONNECTED;
parent->sk_data_ready(parent, 0);
- write_unlock_bh(&list->lock);
+ write_unlock_bh(&conn->chan_lock);
clean:
bh_unlock_sock(parent);
@@ -693,7 +678,6 @@ clean:
static void l2cap_conn_ready(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
@@ -701,10 +685,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
if (!conn->hcon->out && conn->hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
- for (chan = l->head; chan; chan = chan->next_c) {
+ list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
+
bh_lock_sock(sk);
if (conn->hcon->type == LE_LINK) {
@@ -724,26 +709,27 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
/* Notify sockets that we cannot guaranty reliability anymore */
static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct l2cap_chan *chan;
+ struct sock *sk;
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
+
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ sk = chan->sk;
- for (chan = l->head; chan; chan = chan->next_c) {
- struct sock *sk = chan->sk;
if (l2cap_pi(sk)->force_reliable)
sk->sk_err = err;
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
static void l2cap_info_timeout(unsigned long arg)
@@ -783,7 +769,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->feat_mask = 0;
spin_lock_init(&conn->lock);
- rwlock_init(&conn->chan_list.lock);
+ rwlock_init(&conn->chan_lock);
+
+ INIT_LIST_HEAD(&conn->chan_l);
if (hcon->type != LE_LINK)
setup_timer(&conn->info_timer, l2cap_info_timeout,
@@ -797,7 +785,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
static void l2cap_conn_del(struct hci_conn *hcon, int err)
{
struct l2cap_conn *conn = hcon->l2cap_data;
- struct l2cap_chan *chan;
+ struct l2cap_chan *chan, *l;
struct sock *sk;
if (!conn)
@@ -808,7 +796,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree_skb(conn->rx_skb);
/* Kill channels */
- while ((chan = conn->chan_list.head)) {
+ list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
sk = chan->sk;
bh_lock_sock(sk);
l2cap_chan_del(chan, err);
@@ -825,10 +813,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
- struct l2cap_chan_list *l = &conn->chan_list;
- write_lock_bh(&l->lock);
+ write_lock_bh(&conn->chan_lock);
__l2cap_chan_add(conn, chan);
- write_unlock_bh(&l->lock);
+ write_unlock_bh(&conn->chan_lock);
}
/* ---- Socket interface ---- */
@@ -1426,14 +1413,13 @@ static void l2cap_chan_ready(struct sock *sk)
/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct sk_buff *nskb;
struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
- for (chan = l->head; chan; chan = chan->next_c) {
+ read_lock(&conn->chan_lock);
+ list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
if (sk->sk_type != SOCK_RAW)
continue;
@@ -1448,7 +1434,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
/* ---- L2CAP signalling commands ---- */
@@ -2015,7 +2001,6 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
- struct l2cap_chan_list *list = &conn->chan_list;
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan;
@@ -2062,11 +2047,11 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto response;
}
- write_lock_bh(&list->lock);
+ write_lock_bh(&conn->chan_lock);
/* Check if we already have channel with that dcid */
- if (__l2cap_get_chan_by_dcid(list, scid)) {
- write_unlock_bh(&list->lock);
+ if (__l2cap_get_chan_by_dcid(conn, scid)) {
+ write_unlock_bh(&conn->chan_lock);
sock_set_flag(sk, SOCK_ZAPPED);
l2cap_sock_kill(sk);
goto response;
@@ -2115,7 +2100,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
status = L2CAP_CS_NO_INFO;
}
- write_unlock_bh(&list->lock);
+ write_unlock_bh(&conn->chan_lock);
response:
bh_unlock_sock(parent);
@@ -2169,11 +2154,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
if (scid) {
- chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ chan = l2cap_get_chan_by_scid(conn, scid);
if (!chan)
return -EFAULT;
} else {
- chan = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
+ chan = l2cap_get_chan_by_ident(conn, cmd->ident);
if (!chan)
return -EFAULT;
}
@@ -2243,7 +2228,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
- chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+ chan = l2cap_get_chan_by_scid(conn, dcid);
if (!chan)
return -ENOENT;
@@ -2338,7 +2323,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
scid, flags, result);
- chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ chan = l2cap_get_chan_by_scid(conn, scid);
if (!chan)
return 0;
@@ -2418,7 +2403,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
- chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+ chan = l2cap_get_chan_by_scid(conn, dcid);
if (!chan)
return 0;
@@ -2458,7 +2443,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
- chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+ chan = l2cap_get_chan_by_scid(conn, scid);
if (!chan)
return 0;
@@ -3612,7 +3597,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
u8 tx_seq;
int len;
- chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+ chan = l2cap_get_chan_by_scid(conn, cid);
if (!chan) {
BT_DBG("unknown cid 0x%4.4x", cid);
goto drop;
@@ -3855,21 +3840,20 @@ static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
{
- struct l2cap_chan_list *l;
struct l2cap_conn *conn = hcon->l2cap_data;
struct l2cap_chan *chan;
+ struct sock *sk;
if (!conn)
return 0;
- l = &conn->chan_list;
-
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
+
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ sk = chan->sk;
- for (chan = l->head; chan; chan = chan->next_c) {
- struct sock *sk = chan->sk;
bh_lock_sock(sk);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
@@ -3923,7 +3907,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
return 0;
}
@@ -3980,7 +3964,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
goto drop;
}
- chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+ chan = l2cap_get_chan_by_scid(conn, cid);
if (chan && chan->sk) {
struct sock *sk = chan->sk;
@@ -3996,6 +3980,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
bh_unlock_sock(sk);
}
+
/* Allocate skb for the complete frame (with header) */
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!conn->rx_skb)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 03/15] Bluetooth: Remove struct del_list
2011-04-01 22:33 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 04/15] Bluetooth: Move ident to struct l2cap_chan Gustavo F. Padovan
2011-04-04 20:28 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Anderson Lizardo
1 sibling, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As we use struct list_head to keep L2CAP channels list the workaround with
del_list is not needed anymore.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 5 -----
net/bluetooth/l2cap_core.c | 24 +++++++-----------------
2 files changed, 7 insertions(+), 22 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ddf4bc5..d24b51c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -309,11 +309,6 @@ struct l2cap_conn {
rwlock_t chan_lock;
};
-struct sock_del_list {
- struct sock *sk;
- struct list_head list;
-};
-
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ce68896..3047c47 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -487,16 +487,13 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
/* ---- L2CAP connections ---- */
static void l2cap_conn_start(struct l2cap_conn *conn)
{
- struct sock_del_list del, *tmp1, *tmp2;
- struct l2cap_chan *chan;
+ struct l2cap_chan *chan, *tmp;
BT_DBG("conn %p", conn);
- INIT_LIST_HEAD(&del.list);
-
read_lock(&conn->chan_lock);
- list_for_each_entry(chan, &conn->chan_l, list) {
+ list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
struct sock *sk = chan->sk;
bh_lock_sock(sk);
@@ -520,10 +517,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
conn->feat_mask)
&& l2cap_pi(sk)->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
- tmp1 = kzalloc(sizeof(struct sock_del_list),
- GFP_ATOMIC);
- tmp1->sk = sk;
- list_add_tail(&tmp1->list, &del.list);
+ /* __l2cap_sock_close() calls list_del(chan)
+ * so release the lock */
+ read_unlock_bh(&conn->chan_lock);
+ __l2cap_sock_close(sk, ECONNRESET);
+ read_lock_bh(&conn->chan_lock);
bh_unlock_sock(sk);
continue;
}
@@ -579,14 +577,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
}
read_unlock(&conn->chan_lock);
-
- list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
- bh_lock_sock(tmp1->sk);
- __l2cap_sock_close(tmp1->sk, ECONNRESET);
- bh_unlock_sock(tmp1->sk);
- list_del(&tmp1->list);
- kfree(tmp1);
- }
}
/* Find socket with cid and source bdaddr.
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 04/15] Bluetooth: Move ident to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 03/15] Bluetooth: Remove struct del_list Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 05/15] Bluetooth: Move conf_{req,rsp} stuff " Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
ident is chan property, no need to reside on socket.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 4 ++--
net/bluetooth/l2cap_core.c | 38 +++++++++++++++++++-------------------
net/bluetooth/l2cap_sock.c | 4 ++--
3 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d24b51c..81829e5 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -279,6 +279,8 @@ struct l2cap_conn_param_update_rsp {
/* ----- L2CAP channels and connections ----- */
struct l2cap_chan {
struct sock *sk;
+ __u8 ident;
+
struct list_head list;
};
@@ -363,8 +365,6 @@ struct l2cap_pinfo {
__u16 partial_sdu_len;
struct sk_buff *sdu;
- __u8 ident;
-
__u8 tx_win;
__u8 max_tx;
__u8 remote_tx_win;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3047c47..778b30b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -118,8 +118,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8
struct l2cap_chan *c;
list_for_each_entry(c, &conn->chan_l, list) {
- struct sock *s = c->sk;
- if (l2cap_pi(s)->ident == ident)
+ if (c->ident == ident)
return c;
}
return NULL;
@@ -410,8 +409,9 @@ static inline int __l2cap_no_conn_pending(struct sock *sk)
return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
}
-static void l2cap_do_start(struct sock *sk)
+static void l2cap_do_start(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
@@ -423,11 +423,11 @@ static void l2cap_do_start(struct sock *sk)
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_REQ, sizeof(req), &req);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
+ sizeof(req), &req);
}
} else {
struct l2cap_info_req req;
@@ -529,11 +529,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_REQ, sizeof(req), &req);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
+ sizeof(req), &req);
} else if (sk->sk_state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
@@ -558,8 +558,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
}
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
rsp.result != L2CAP_CR_SUCCESS) {
@@ -694,7 +694,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
} else if (sk->sk_state == BT_CONNECT)
- l2cap_do_start(sk);
+ l2cap_do_start(chan);
bh_unlock_sock(sk);
}
@@ -905,7 +905,7 @@ int l2cap_do_connect(struct sock *sk)
if (l2cap_check_security(sk))
sk->sk_state = BT_CONNECTED;
} else
- l2cap_do_start(sk);
+ l2cap_do_start(chan);
}
err = 0;
@@ -2065,7 +2065,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
- l2cap_pi(sk)->ident = cmd->ident;
+ chan->ident = cmd->ident;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_check_security(sk)) {
@@ -2158,7 +2158,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
switch (result) {
case L2CAP_CR_SUCCESS:
sk->sk_state = BT_CONFIG;
- l2cap_pi(sk)->ident = 0;
+ chan->ident = 0;
l2cap_pi(sk)->dcid = dcid;
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
@@ -3864,10 +3864,10 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+ l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
} else {
l2cap_sock_clear_timer(sk);
@@ -3890,8 +3890,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
}
bh_unlock_sock(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 7df8118..cad4bc7 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -818,7 +818,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
+ l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->chan->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
@@ -921,7 +921,7 @@ void __l2cap_sock_close(struct sock *sk, int reason)
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+ l2cap_send_cmd(conn, l2cap_pi(sk)->chan->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 05/15] Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 04/15] Bluetooth: Move ident to struct l2cap_chan Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 06/15] Bluetooth: clean up l2cap_sock_recvmsg() Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
They are also l2cap_chan specific.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 11 ++++---
net/bluetooth/l2cap_core.c | 55 +++++++++++++++++++++--------------------
net/bluetooth/l2cap_sock.c | 8 +++---
3 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 81829e5..bf91828 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -281,6 +281,11 @@ struct l2cap_chan {
struct sock *sk;
__u8 ident;
+ __u8 conf_req[64];
+ __u8 conf_len;
+ __u8 num_conf_req;
+ __u8 num_conf_rsp;
+
struct list_head list;
};
@@ -337,8 +342,6 @@ struct l2cap_pinfo {
__u16 omtu;
__u16 flush_to;
__u8 mode;
- __u8 num_conf_req;
- __u8 num_conf_rsp;
__u8 fcs;
__u8 sec_level;
@@ -346,8 +349,6 @@ struct l2cap_pinfo {
__u8 force_reliable;
__u8 flushable;
- __u8 conf_req[64];
- __u8 conf_len;
__u8 conf_state;
__u16 conn_state;
@@ -447,7 +448,7 @@ void l2cap_cleanup_sockets(void);
u8 l2cap_get_ident(struct l2cap_conn *conn);
void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
-int l2cap_build_conf_req(struct sock *sk, void *data);
+int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
int __l2cap_wait_ack(struct sock *sk);
struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 778b30b..95e488f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -569,8 +569,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
bh_unlock_sock(sk);
@@ -1599,8 +1599,9 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
}
}
-int l2cap_build_conf_req(struct sock *sk, void *data)
+int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = pi->mode };
@@ -1608,7 +1609,7 @@ int l2cap_build_conf_req(struct sock *sk, void *data)
BT_DBG("sk %p", sk);
- if (pi->num_conf_req || pi->num_conf_rsp)
+ if (chan->num_conf_req || chan->num_conf_rsp)
goto done;
switch (pi->mode) {
@@ -1697,20 +1698,20 @@ done:
return ptr - data;
}
-static int l2cap_parse_conf_req(struct sock *sk, void *data)
+static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
- void *req = pi->conf_req;
- int len = pi->conf_len;
+ void *req = chan->conf_req;
+ int len = chan->conf_len;
int type, hint, olen;
unsigned long val;
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
u16 mtu = L2CAP_DEFAULT_MTU;
u16 result = L2CAP_CONF_SUCCESS;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
@@ -1751,7 +1752,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
}
}
- if (pi->num_conf_rsp || pi->num_conf_req > 1)
+ if (chan->num_conf_rsp || chan->num_conf_req > 1)
goto done;
switch (pi->mode) {
@@ -1774,7 +1775,7 @@ done:
result = L2CAP_CONF_UNACCEPT;
rfc.mode = pi->mode;
- if (pi->num_conf_rsp == 1)
+ if (chan->num_conf_rsp == 1)
return -ECONNREFUSED;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
@@ -1993,7 +1994,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
{
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
- struct l2cap_chan *chan;
+ struct l2cap_chan *chan = NULL;
struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
@@ -2116,13 +2117,13 @@ sendresp:
L2CAP_INFO_REQ, sizeof(info), &info);
}
- if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
+ if (chan && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
result == L2CAP_CR_SUCCESS) {
u8 buf[128];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
return 0;
@@ -2168,8 +2169,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, req), req);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, req), req);
+ chan->num_conf_req++;
break;
case L2CAP_CR_PEND:
@@ -2235,7 +2236,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req);
- if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
+ if (chan->conf_len + len > sizeof(chan->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(sk, rsp,
L2CAP_CONF_REJECT, flags), rsp);
@@ -2243,8 +2244,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
}
/* Store config. */
- memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
- l2cap_pi(sk)->conf_len += len;
+ memcpy(chan->conf_req + chan->conf_len, req->data, len);
+ chan->conf_len += len;
if (flags & 0x0001) {
/* Incomplete config. Send empty response. */
@@ -2255,17 +2256,17 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
}
/* Complete config. */
- len = l2cap_parse_conf_req(sk, rsp);
+ len = l2cap_parse_conf_req(chan, rsp);
if (len < 0) {
l2cap_send_disconn_req(conn, sk, ECONNRESET);
goto unlock;
}
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
- l2cap_pi(sk)->num_conf_rsp++;
+ chan->num_conf_rsp++;
/* Reset config buffer. */
- l2cap_pi(sk)->conf_len = 0;
+ chan->conf_len = 0;
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
goto unlock;
@@ -2289,8 +2290,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
u8 buf[64];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
unlock:
@@ -2325,7 +2326,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
break;
case L2CAP_CONF_UNACCEPT:
- if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
+ if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
@@ -2344,7 +2345,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_CONF_REQ, len, req);
- l2cap_pi(sk)->num_conf_req++;
+ chan->num_conf_req++;
if (result != L2CAP_CONF_SUCCESS)
goto done;
break;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index cad4bc7..244475e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -810,6 +810,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
struct l2cap_conn_rsp rsp;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
u8 buf[128];
sk->sk_state = BT_CONFIG;
@@ -818,7 +819,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->chan->ident,
+ l2cap_send_cmd(l2cap_pi(sk)->conn, chan->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
@@ -828,8 +829,8 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
release_sock(sk);
return 0;
@@ -1035,7 +1036,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
}
/* Default config options */
- pi->conf_len = 0;
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
skb_queue_head_init(TX_QUEUE(sk));
skb_queue_head_init(SREJ_QUEUE(sk));
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 06/15] Bluetooth: clean up l2cap_sock_recvmsg()
2011-04-01 22:33 ` [PATCH 05/15] Bluetooth: Move conf_{req,rsp} stuff " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
Move some channel specific stuff to l2cap_core.c, this will make things
more clear.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 3 +--
net/bluetooth/l2cap_core.c | 28 +++++++++++++++++++++++++++-
net/bluetooth/l2cap_sock.c | 25 +------------------------
3 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index bf91828..4692413 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -446,9 +446,8 @@ extern struct bt_sock_list l2cap_sk_list;
int l2cap_init_sockets(void);
void l2cap_cleanup_sockets(void);
-u8 l2cap_get_ident(struct l2cap_conn *conn);
void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
-int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
+void __l2cap_connect_rsp_defer(struct sock *sk);
int __l2cap_wait_ack(struct sock *sk);
struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 95e488f..26c187e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -70,6 +70,7 @@ static void l2cap_busy_work(struct work_struct *work);
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
u8 code, u8 ident, u16 dlen, void *data);
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
@@ -1599,7 +1600,7 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
}
}
-int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
@@ -1935,6 +1936,31 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
return ptr - data;
}
+void __l2cap_connect_rsp_defer(struct sock *sk)
+{
+ struct l2cap_conn_rsp rsp;
+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+ u8 buf[128];
+
+ sk->sk_state = BT_CONFIG;
+
+ rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
+ rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
+ rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+ l2cap_send_cmd(conn, chan->ident,
+ L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+
+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
+ return;
+
+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
+}
+
static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 244475e..450f57b 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -808,30 +808,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
lock_sock(sk);
if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
- struct l2cap_conn_rsp rsp;
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
- struct l2cap_chan *chan = l2cap_pi(sk)->chan;
- u8 buf[128];
-
- sk->sk_state = BT_CONFIG;
-
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
- rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
- rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(l2cap_pi(sk)->conn, chan->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
-
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
- release_sock(sk);
- return 0;
- }
-
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
- l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
- chan->num_conf_req++;
-
+ __l2cap_connect_rsp_defer(sk);
release_sock(sk);
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 06/15] Bluetooth: clean up l2cap_sock_recvmsg() Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 08/15] Bluetooth: Move of ERTM *_seq vars " Gustavo F. Padovan
2011-04-04 20:50 ` [PATCH 07/15] Bluetooth: Move conn_state " Anderson Lizardo
0 siblings, 2 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
This is part of "moving things to l2cap_chan". As one the first move it
triggered a big number of changes in the funcions parameters, basically
changing the struct sock param to struct l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 5 +-
net/bluetooth/l2cap_core.c | 391 +++++++++++++++++++++-------------------
net/bluetooth/l2cap_sock.c | 16 +-
3 files changed, 217 insertions(+), 195 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 4692413..82d5b81 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -286,6 +286,8 @@ struct l2cap_chan {
__u8 num_conf_req;
__u8 num_conf_rsp;
+ __u16 conn_state;
+
struct list_head list;
};
@@ -350,7 +352,6 @@ struct l2cap_pinfo {
__u8 flushable;
__u8 conf_state;
- __u16 conn_state;
__u8 next_tx_seq;
__u8 expected_ack_seq;
@@ -456,7 +457,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len);
void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
void l2cap_streaming_send(struct sock *sk);
-int l2cap_ertm_send(struct sock *sk);
+int l2cap_ertm_send(struct l2cap_chan *chan);
void l2cap_sock_set_timer(struct sock *sk, long timeout);
void l2cap_sock_clear_timer(struct sock *sk);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 26c187e..695f42b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -340,10 +340,11 @@ void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *d
hci_send_acl(conn->hcon, skb, flags);
}
-static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
{
struct sk_buff *skb;
struct l2cap_hdr *lh;
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct l2cap_conn *conn = pi->conn;
struct sock *sk = (struct sock *)pi;
int count, hlen = L2CAP_HDR_SIZE + 2;
@@ -360,14 +361,14 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
count = min_t(unsigned int, conn->mtu, hlen);
control |= L2CAP_CTRL_FRAME_TYPE;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_PBIT) {
control |= L2CAP_CTRL_POLL;
- pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_PBIT;
}
skb = bt_skb_alloc(count, GFP_ATOMIC);
@@ -392,17 +393,19 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
hci_send_acl(pi->conn->hcon, skb, flags);
}
-static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
{
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
+
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
} else
control |= L2CAP_SUPER_RCV_READY;
control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
static inline int __l2cap_no_conn_pending(struct sock *sk)
@@ -950,9 +953,10 @@ int __l2cap_wait_ack(struct sock *sk)
static void l2cap_monitor_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
+ struct sock *sk = chan->sk;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
bh_lock_sock(sk);
if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
@@ -964,13 +968,14 @@ static void l2cap_monitor_timeout(unsigned long arg)
l2cap_pi(sk)->retry_count++;
__mod_monitor_timer();
- l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
bh_unlock_sock(sk);
}
static void l2cap_retrans_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
+ struct sock *sk = chan->sk;
BT_DBG("sk %p", sk);
@@ -978,9 +983,9 @@ static void l2cap_retrans_timeout(unsigned long arg)
l2cap_pi(sk)->retry_count = 1;
__mod_monitor_timer();
- l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+ chan->conn_state |= L2CAP_CONN_WAIT_F;
- l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
bh_unlock_sock(sk);
}
@@ -1041,8 +1046,9 @@ void l2cap_streaming_send(struct sock *sk)
}
}
-static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
+static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb, *tx_skb;
u16 control, fcs;
@@ -1070,9 +1076,9 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
bt_cb(skb)->retries++;
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
@@ -1088,9 +1094,10 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
l2cap_do_send(sk, tx_skb);
}
-int l2cap_ertm_send(struct sock *sk)
+int l2cap_ertm_send(struct l2cap_chan *chan)
{
struct sk_buff *skb, *tx_skb;
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
int nsent = 0;
@@ -1113,9 +1120,9 @@ int l2cap_ertm_send(struct sock *sk)
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
control &= L2CAP_CTRL_SAR;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
@@ -1150,8 +1157,9 @@ int l2cap_ertm_send(struct sock *sk)
return nsent;
}
-static int l2cap_retransmit_frames(struct sock *sk)
+static int l2cap_retransmit_frames(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
int ret;
@@ -1159,32 +1167,32 @@ static int l2cap_retransmit_frames(struct sock *sk)
sk->sk_send_head = TX_QUEUE(sk)->next;
pi->next_tx_seq = pi->expected_ack_seq;
- ret = l2cap_ertm_send(sk);
+ ret = l2cap_ertm_send(chan);
return ret;
}
-static void l2cap_send_ack(struct l2cap_pinfo *pi)
+static void l2cap_send_ack(struct l2cap_chan *chan)
{
- struct sock *sk = (struct sock *)pi;
+ struct sock *sk = chan->sk;
u16 control = 0;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= l2cap_pi(sk)->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
- l2cap_send_sframe(pi, control);
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
+ l2cap_send_sframe(chan, control);
return;
}
- if (l2cap_ertm_send(sk) > 0)
+ if (l2cap_ertm_send(chan) > 0)
return;
control |= L2CAP_SUPER_RCV_READY;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
-static void l2cap_send_srejtail(struct sock *sk)
+static void l2cap_send_srejtail(struct l2cap_chan *chan)
{
struct srej_list *tail;
u16 control;
@@ -1192,10 +1200,10 @@ static void l2cap_send_srejtail(struct sock *sk)
control = L2CAP_SUPER_SELECT_REJECT;
control |= L2CAP_CTRL_FINAL;
- tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
+ tail = list_entry(SREJ_LIST(chan->sk)->prev, struct srej_list, list);
control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(l2cap_pi(sk), control);
+ l2cap_send_sframe(chan, control);
}
static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
@@ -1557,15 +1565,17 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
static void l2cap_ack_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
- bh_lock_sock(sk);
- l2cap_send_ack(l2cap_pi(sk));
- bh_unlock_sock(sk);
+ bh_lock_sock(chan->sk);
+ l2cap_send_ack(chan);
+ bh_unlock_sock(chan->sk);
}
-static inline void l2cap_ertm_init(struct sock *sk)
+static inline void l2cap_ertm_init(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
+
l2cap_pi(sk)->expected_ack_seq = 0;
l2cap_pi(sk)->unacked_frames = 0;
l2cap_pi(sk)->buffer_seq = 0;
@@ -1573,11 +1583,11 @@ static inline void l2cap_ertm_init(struct sock *sk)
l2cap_pi(sk)->frames_sent = 0;
setup_timer(&l2cap_pi(sk)->retrans_timer,
- l2cap_retrans_timeout, (unsigned long) sk);
+ l2cap_retrans_timeout, (unsigned long) chan);
setup_timer(&l2cap_pi(sk)->monitor_timer,
- l2cap_monitor_timeout, (unsigned long) sk);
+ l2cap_monitor_timeout, (unsigned long) chan);
setup_timer(&l2cap_pi(sk)->ack_timer,
- l2cap_ack_timeout, (unsigned long) sk);
+ l2cap_ack_timeout, (unsigned long) chan);
__skb_queue_head_init(SREJ_QUEUE(sk));
__skb_queue_head_init(BUSY_QUEUE(sk));
@@ -2306,7 +2316,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi(sk)->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
- l2cap_ertm_init(sk);
+ l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
goto unlock;
@@ -2397,7 +2407,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi(sk)->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
- l2cap_ertm_init(sk);
+ l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
}
@@ -2778,30 +2788,30 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
return 0;
}
-static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
+static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u16 control = 0;
pi->frames_sent = 0;
control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- l2cap_send_sframe(pi, control);
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ l2cap_send_sframe(chan, control);
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
}
- if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
- l2cap_retransmit_frames(sk);
+ if (chan->conn_state & L2CAP_CONN_REMOTE_BUSY)
+ l2cap_retransmit_frames(chan);
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
- if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
+ if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
pi->frames_sent == 0) {
control |= L2CAP_SUPER_RCV_READY;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
}
@@ -2848,25 +2858,25 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return 0;
}
-static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct sk_buff *_skb;
int err;
switch (control & L2CAP_CTRL_SAR) {
case L2CAP_SDU_UNSEGMENTED:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU)
goto drop;
- err = sock_queue_rcv_skb(sk, skb);
+ err = sock_queue_rcv_skb(chan->sk, skb);
if (!err)
return err;
break;
case L2CAP_SDU_START:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU)
goto drop;
pi->sdu_len = get_unaligned_le16(skb->data);
@@ -2885,12 +2895,12 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c
memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
- pi->conn_state |= L2CAP_CONN_SAR_SDU;
+ chan->conn_state |= L2CAP_CONN_SAR_SDU;
pi->partial_sdu_len = skb->len;
break;
case L2CAP_SDU_CONTINUE:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
if (!pi->sdu)
@@ -2905,13 +2915,13 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c
break;
case L2CAP_SDU_END:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
if (!pi->sdu)
goto disconnect;
- if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
+ if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) {
pi->partial_sdu_len += skb->len;
if (pi->partial_sdu_len > pi->imtu)
@@ -2925,19 +2935,19 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c
_skb = skb_clone(pi->sdu, GFP_ATOMIC);
if (!_skb) {
- pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+ chan->conn_state |= L2CAP_CONN_SAR_RETRY;
return -ENOMEM;
}
- err = sock_queue_rcv_skb(sk, _skb);
+ err = sock_queue_rcv_skb(chan->sk, _skb);
if (err < 0) {
kfree_skb(_skb);
- pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+ chan->conn_state |= L2CAP_CONN_SAR_RETRY;
return err;
}
- pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
- pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
+ chan->conn_state &= ~L2CAP_CONN_SAR_RETRY;
+ chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
kfree_skb(pi->sdu);
break;
@@ -2951,13 +2961,14 @@ drop:
pi->sdu = NULL;
disconnect:
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET);
kfree_skb(skb);
return 0;
}
-static int l2cap_try_push_rx_skb(struct sock *sk)
+static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb;
u16 control;
@@ -2965,7 +2976,7 @@ static int l2cap_try_push_rx_skb(struct sock *sk)
while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
- err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+ err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err < 0) {
skb_queue_head(BUSY_QUEUE(sk), skb);
return -EBUSY;
@@ -2974,22 +2985,22 @@ static int l2cap_try_push_rx_skb(struct sock *sk)
pi->buffer_seq = (pi->buffer_seq + 1) % 64;
}
- if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
+ if (!(chan->conn_state & L2CAP_CONN_RNR_SENT))
goto done;
control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
l2cap_pi(sk)->retry_count = 1;
del_timer(&pi->retrans_timer);
__mod_monitor_timer();
- l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+ chan->conn_state |= L2CAP_CONN_WAIT_F;
done:
- pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
- pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
+ chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_RNR_SENT;
BT_DBG("sk %p, Exit local busy", sk);
@@ -3033,7 +3044,7 @@ static void l2cap_busy_work(struct work_struct *work)
if (err)
break;
- if (l2cap_try_push_rx_skb(sk) == 0)
+ if (l2cap_try_push_rx_skb(l2cap_pi(sk)->chan) == 0)
break;
}
@@ -3043,20 +3054,21 @@ static void l2cap_busy_work(struct work_struct *work)
release_sock(sk);
}
-static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
int sctrl, err;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
__skb_queue_tail(BUSY_QUEUE(sk), skb);
- return l2cap_try_push_rx_skb(sk);
+ return l2cap_try_push_rx_skb(chan);
}
- err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+ err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err >= 0) {
pi->buffer_seq = (pi->buffer_seq + 1) % 64;
return err;
@@ -3065,15 +3077,15 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
/* Busy Condition */
BT_DBG("sk %p, Enter local busy", sk);
- pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
+ chan->conn_state |= L2CAP_CONN_LOCAL_BUSY;
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
__skb_queue_tail(BUSY_QUEUE(sk), skb);
sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
sctrl |= L2CAP_SUPER_RCV_NOT_READY;
- l2cap_send_sframe(pi, sctrl);
+ l2cap_send_sframe(chan, sctrl);
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
del_timer(&pi->ack_timer);
@@ -3082,9 +3094,9 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
return err;
}
-static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct sk_buff *_skb;
int err = -EINVAL;
@@ -3095,19 +3107,19 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb,
switch (control & L2CAP_CTRL_SAR) {
case L2CAP_SDU_UNSEGMENTED:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
kfree_skb(pi->sdu);
break;
}
- err = sock_queue_rcv_skb(sk, skb);
+ err = sock_queue_rcv_skb(chan->sk, skb);
if (!err)
return 0;
break;
case L2CAP_SDU_START:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
kfree_skb(pi->sdu);
break;
}
@@ -3128,13 +3140,13 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb,
memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
- pi->conn_state |= L2CAP_CONN_SAR_SDU;
+ chan->conn_state |= L2CAP_CONN_SAR_SDU;
pi->partial_sdu_len = skb->len;
err = 0;
break;
case L2CAP_SDU_CONTINUE:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
@@ -3148,12 +3160,12 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb,
break;
case L2CAP_SDU_END:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
- pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
+ chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
pi->partial_sdu_len += skb->len;
if (pi->partial_sdu_len > pi->imtu)
@@ -3161,7 +3173,7 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb,
if (pi->partial_sdu_len == pi->sdu_len) {
_skb = skb_clone(pi->sdu, GFP_ATOMIC);
- err = sock_queue_rcv_skb(sk, _skb);
+ err = sock_queue_rcv_skb(chan->sk, _skb);
if (err < 0)
kfree_skb(_skb);
}
@@ -3176,8 +3188,9 @@ drop:
return err;
}
-static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
+static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
{
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
u16 control;
@@ -3187,16 +3200,16 @@ static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
skb = skb_dequeue(SREJ_QUEUE(sk));
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
- l2cap_ertm_reassembly_sdu(sk, skb, control);
+ l2cap_ertm_reassembly_sdu(chan, skb, control);
l2cap_pi(sk)->buffer_seq_srej =
(l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
tx_seq = (tx_seq + 1) % 64;
}
}
-static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
+static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct sock *sk = chan->sk;
struct srej_list *l, *tmp;
u16 control;
@@ -3208,14 +3221,15 @@ static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
}
control = L2CAP_SUPER_SELECT_REJECT;
control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
list_del(&l->list);
list_add_tail(&l->list, SREJ_LIST(sk));
}
}
-static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
+static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct srej_list *new;
u16 control;
@@ -3223,7 +3237,7 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
while (tx_seq != pi->expected_tx_seq) {
control = L2CAP_SUPER_SELECT_REJECT;
control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
new->tx_seq = pi->expected_tx_seq;
@@ -3233,8 +3247,9 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
}
-static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
@@ -3243,15 +3258,15 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
int num_to_ack = (pi->tx_win/6) + 1;
int err = 0;
- BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
- rx_control);
+ BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len,
+ tx_seq, rx_control);
if (L2CAP_CTRL_FINAL & rx_control &&
- l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
+ chan->conn_state & L2CAP_CONN_WAIT_F) {
del_timer(&pi->monitor_timer);
if (pi->unacked_frames > 0)
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+ chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
pi->expected_ack_seq = req_seq;
@@ -3270,25 +3285,25 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
goto drop;
}
- if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
+ if (chan->conn_state == L2CAP_CONN_LOCAL_BUSY)
goto drop;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
struct srej_list *first;
first = list_first_entry(SREJ_LIST(sk),
struct srej_list, list);
if (tx_seq == first->tx_seq) {
l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
- l2cap_check_srej_gap(sk, tx_seq);
+ l2cap_check_srej_gap(chan, tx_seq);
list_del(&first->list);
kfree(first);
if (list_empty(SREJ_LIST(sk))) {
pi->buffer_seq = pi->buffer_seq_srej;
- pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
- l2cap_send_ack(pi);
+ chan->conn_state &= ~L2CAP_CONN_SREJ_SENT;
+ l2cap_send_ack(chan);
BT_DBG("sk %p, Exit SREJ_SENT", sk);
}
} else {
@@ -3300,11 +3315,11 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
list_for_each_entry(l, SREJ_LIST(sk), list) {
if (l->tx_seq == tx_seq) {
- l2cap_resend_srejframe(sk, tx_seq);
+ l2cap_resend_srejframe(chan, tx_seq);
return 0;
}
}
- l2cap_send_srejframe(sk, tx_seq);
+ l2cap_send_srejframe(chan, tx_seq);
}
} else {
expected_tx_seq_offset =
@@ -3316,7 +3331,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
if (tx_seq_offset < expected_tx_seq_offset)
goto drop;
- pi->conn_state |= L2CAP_CONN_SREJ_SENT;
+ chan->conn_state |= L2CAP_CONN_SREJ_SENT;
BT_DBG("sk %p, Enter SREJ", sk);
@@ -3327,9 +3342,9 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
__skb_queue_head_init(BUSY_QUEUE(sk));
l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
- pi->conn_state |= L2CAP_CONN_SEND_PBIT;
+ chan->conn_state |= L2CAP_CONN_SEND_PBIT;
- l2cap_send_srejframe(sk, tx_seq);
+ l2cap_send_srejframe(chan, tx_seq);
del_timer(&pi->ack_timer);
}
@@ -3338,29 +3353,29 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
expected:
pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
__skb_queue_tail(SREJ_QUEUE(sk), skb);
return 0;
}
- err = l2cap_push_rx_skb(sk, skb, rx_control);
+ err = l2cap_push_rx_skb(chan, skb, rx_control);
if (err < 0)
return 0;
if (rx_control & L2CAP_CTRL_FINAL) {
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
}
__mod_ack_timer();
pi->num_acked = (pi->num_acked + 1) % num_to_ack;
if (pi->num_acked == num_to_ack - 1)
- l2cap_send_ack(pi);
+ l2cap_send_ack(chan);
return 0;
@@ -3369,8 +3384,9 @@ drop:
return 0;
}
-static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control)
{
+ struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
@@ -3380,154 +3396,156 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
l2cap_drop_acked_frames(sk);
if (rx_control & L2CAP_CTRL_POLL) {
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
(pi->unacked_frames > 0))
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- l2cap_send_srejtail(sk);
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ l2cap_send_srejtail(chan);
} else {
- l2cap_send_i_or_rr_or_rnr(sk);
+ l2cap_send_i_or_rr_or_rnr(chan);
}
} else if (rx_control & L2CAP_CTRL_FINAL) {
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
} else {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
(pi->unacked_frames > 0))
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
- l2cap_send_ack(pi);
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT)
+ l2cap_send_ack(chan);
else
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
}
}
-static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ l2cap_drop_acked_frames(chan->sk);
if (rx_control & L2CAP_CTRL_FINAL) {
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
} else {
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
- if (pi->conn_state & L2CAP_CONN_WAIT_F)
- pi->conn_state |= L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_WAIT_F)
+ chan->conn_state |= L2CAP_CONN_REJ_ACT;
}
}
-static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
if (rx_control & L2CAP_CTRL_POLL) {
pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ l2cap_drop_acked_frames(chan->sk);
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
- l2cap_retransmit_one_frame(sk, tx_seq);
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
+ l2cap_retransmit_one_frame(chan, tx_seq);
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+ if (chan->conn_state & L2CAP_CONN_WAIT_F) {
pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+ chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
} else if (rx_control & L2CAP_CTRL_FINAL) {
- if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
+ if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) &&
pi->srej_save_reqseq == tx_seq)
- pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
+ chan->conn_state &= ~L2CAP_CONN_SREJ_ACT;
else
- l2cap_retransmit_one_frame(sk, tx_seq);
+ l2cap_retransmit_one_frame(chan, tx_seq);
} else {
- l2cap_retransmit_one_frame(sk, tx_seq);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+ l2cap_retransmit_one_frame(chan, tx_seq);
+ if (chan->conn_state & L2CAP_CONN_WAIT_F) {
pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+ chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
}
}
-static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state |= L2CAP_CONN_REMOTE_BUSY;
pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ l2cap_drop_acked_frames(chan->sk);
if (rx_control & L2CAP_CTRL_POLL)
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
- if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
+ if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) {
del_timer(&pi->retrans_timer);
if (rx_control & L2CAP_CTRL_POLL)
- l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL);
return;
}
if (rx_control & L2CAP_CTRL_POLL)
- l2cap_send_srejtail(sk);
+ l2cap_send_srejtail(chan);
else
- l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
+ l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY);
}
-static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
- BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ struct sock *sk = chan->sk;
+
+ BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len);
if (L2CAP_CTRL_FINAL & rx_control &&
- l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
+ chan->conn_state & L2CAP_CONN_WAIT_F) {
del_timer(&l2cap_pi(sk)->monitor_timer);
if (l2cap_pi(sk)->unacked_frames > 0)
__mod_retrans_timer();
- l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
+ chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
switch (rx_control & L2CAP_CTRL_SUPERVISE) {
case L2CAP_SUPER_RCV_READY:
- l2cap_data_channel_rrframe(sk, rx_control);
+ l2cap_data_channel_rrframe(chan, rx_control);
break;
case L2CAP_SUPER_REJECT:
- l2cap_data_channel_rejframe(sk, rx_control);
+ l2cap_data_channel_rejframe(chan, rx_control);
break;
case L2CAP_SUPER_SELECT_REJECT:
- l2cap_data_channel_srejframe(sk, rx_control);
+ l2cap_data_channel_srejframe(chan, rx_control);
break;
case L2CAP_SUPER_RCV_NOT_READY:
- l2cap_data_channel_rnrframe(sk, rx_control);
+ l2cap_data_channel_rnrframe(chan, rx_control);
break;
}
@@ -3537,6 +3555,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
{
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control;
u8 req_seq;
@@ -3587,7 +3606,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
goto drop;
}
- l2cap_data_channel_iframe(sk, control, skb);
+ l2cap_data_channel_iframe(chan, control, skb);
} else {
if (len != 0) {
BT_ERR("%d", len);
@@ -3595,7 +3614,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
goto drop;
}
- l2cap_data_channel_sframe(sk, control, skb);
+ l2cap_data_channel_sframe(chan, control, skb);
}
return 0;
@@ -3676,7 +3695,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
else
pi->expected_tx_seq = (tx_seq + 1) % 64;
- l2cap_streaming_reassembly_sdu(sk, skb, control);
+ l2cap_streaming_reassembly_sdu(chan, skb, control);
goto done;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 450f57b..66ec966 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -778,14 +778,16 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
if (pi->mode == L2CAP_MODE_STREAMING) {
l2cap_streaming_send(sk);
- } else {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->conn_state & L2CAP_CONN_WAIT_F)) {
- err = len;
- break;
- }
- err = l2cap_ertm_send(sk);
+ err = len;
+ break;
+ }
+
+ if ((pi->chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (pi->chan->conn_state & L2CAP_CONN_WAIT_F)) {
+ err = len;
+ break;
}
+ err = l2cap_ertm_send(pi->chan);
if (err >= 0)
err = len;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 08/15] Bluetooth: Move of ERTM *_seq vars to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 09/15] Bluetooth: Move more ERTM stuff " Gustavo F. Padovan
2011-04-04 20:50 ` [PATCH 07/15] Bluetooth: Move conn_state " Anderson Lizardo
1 sibling, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel to stuff to struct l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 20 +++---
net/bluetooth/l2cap_core.c | 128 ++++++++++++++++++++---------------------
net/bluetooth/l2cap_sock.c | 2 +-
3 files changed, 73 insertions(+), 77 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 82d5b81..9b43874 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -288,6 +288,12 @@ struct l2cap_chan {
__u16 conn_state;
+ __u8 next_tx_seq;
+ __u8 expected_ack_seq;
+ __u8 expected_tx_seq;
+ __u8 buffer_seq;
+ __u8 buffer_seq_srej;
+
struct list_head list;
};
@@ -353,11 +359,6 @@ struct l2cap_pinfo {
__u8 conf_state;
- __u8 next_tx_seq;
- __u8 expected_ack_seq;
- __u8 expected_tx_seq;
- __u8 buffer_seq;
- __u8 buffer_seq_srej;
__u8 srej_save_reqseq;
__u8 frames_sent;
__u8 unacked_frames;
@@ -421,17 +422,16 @@ struct l2cap_pinfo {
#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
-static inline int l2cap_tx_window_full(struct sock *sk)
+static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int sub;
- sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+ sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64;
if (sub < 0)
sub += 64;
- return sub == pi->remote_tx_win;
+ return sub == l2cap_pi(ch->sk)->remote_tx_win;
}
#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
@@ -456,7 +456,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size
struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len);
void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
-void l2cap_streaming_send(struct sock *sk);
+void l2cap_streaming_send(struct l2cap_chan *chan);
int l2cap_ertm_send(struct l2cap_chan *chan);
void l2cap_sock_set_timer(struct sock *sk, long timeout);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 695f42b..e00856d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -395,15 +395,13 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
-
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
chan->conn_state |= L2CAP_CONN_RNR_SENT;
} else
control |= L2CAP_SUPER_RCV_READY;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
l2cap_send_sframe(chan, control);
}
@@ -989,13 +987,14 @@ static void l2cap_retrans_timeout(unsigned long arg)
bh_unlock_sock(sk);
}
-static void l2cap_drop_acked_frames(struct sock *sk)
+static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
while ((skb = skb_peek(TX_QUEUE(sk))) &&
l2cap_pi(sk)->unacked_frames) {
- if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
+ if (bt_cb(skb)->tx_seq == chan->expected_ack_seq)
break;
skb = skb_dequeue(TX_QUEUE(sk));
@@ -1024,15 +1023,16 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
hci_send_acl(hcon, skb, flags);
}
-void l2cap_streaming_send(struct sock *sk)
+void l2cap_streaming_send(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
- control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
+ control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
@@ -1042,7 +1042,7 @@ void l2cap_streaming_send(struct sock *sk)
l2cap_do_send(sk, skb);
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
}
}
@@ -1081,7 +1081,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
@@ -1105,7 +1105,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
if (sk->sk_state != BT_CONNECTED)
return -ENOTCONN;
- while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
+ while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) {
if (pi->remote_max_tx &&
bt_cb(skb)->retries == pi->remote_max_tx) {
@@ -1124,8 +1124,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
control |= L2CAP_CTRL_FINAL;
chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
- | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
@@ -1138,8 +1138,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
__mod_retrans_timer();
- bt_cb(skb)->tx_seq = pi->next_tx_seq;
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ bt_cb(skb)->tx_seq = chan->next_tx_seq;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
if (bt_cb(skb)->retries == 1)
pi->unacked_frames++;
@@ -1160,23 +1160,21 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
static int l2cap_retransmit_frames(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int ret;
if (!skb_queue_empty(TX_QUEUE(sk)))
sk->sk_send_head = TX_QUEUE(sk)->next;
- pi->next_tx_seq = pi->expected_ack_seq;
+ chan->next_tx_seq = chan->expected_ack_seq;
ret = l2cap_ertm_send(chan);
return ret;
}
static void l2cap_send_ack(struct l2cap_chan *chan)
{
- struct sock *sk = chan->sk;
u16 control = 0;
- control |= l2cap_pi(sk)->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
@@ -1576,9 +1574,9 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
- l2cap_pi(sk)->expected_ack_seq = 0;
+ chan->expected_ack_seq = 0;
l2cap_pi(sk)->unacked_frames = 0;
- l2cap_pi(sk)->buffer_seq = 0;
+ chan->buffer_seq = 0;
l2cap_pi(sk)->num_acked = 0;
l2cap_pi(sk)->frames_sent = 0;
@@ -2312,8 +2310,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
@@ -2403,8 +2401,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
set_default_fcs(l2cap_pi(sk));
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
@@ -2795,7 +2793,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
pi->frames_sent = 0;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
@@ -2815,10 +2813,10 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
}
}
-static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
+static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
+ struct sock *sk = chan->sk;
struct sk_buff *next_skb;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int tx_seq_offset, next_tx_seq_offset;
bt_cb(skb)->tx_seq = tx_seq;
@@ -2830,7 +2828,7 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return 0;
}
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
@@ -2839,7 +2837,7 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return -EINVAL;
next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
- pi->buffer_seq) % 64;
+ chan->buffer_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
@@ -2982,13 +2980,13 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
return -EBUSY;
}
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
}
if (!(chan->conn_state & L2CAP_CONN_RNR_SENT))
goto done;
- control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
l2cap_send_sframe(chan, control);
l2cap_pi(sk)->retry_count = 1;
@@ -3070,7 +3068,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err >= 0) {
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
return err;
}
@@ -3081,7 +3079,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
__skb_queue_tail(BUSY_QUEUE(sk), skb);
- sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
sctrl |= L2CAP_SUPER_RCV_NOT_READY;
l2cap_send_sframe(chan, sctrl);
@@ -3201,8 +3199,8 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
skb = skb_dequeue(SREJ_QUEUE(sk));
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
l2cap_ertm_reassembly_sdu(chan, skb, control);
- l2cap_pi(sk)->buffer_seq_srej =
- (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
+ chan->buffer_seq_srej =
+ (chan->buffer_seq_srej + 1) % 64;
tx_seq = (tx_seq + 1) % 64;
}
}
@@ -3230,21 +3228,20 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct srej_list *new;
u16 control;
- while (tx_seq != pi->expected_tx_seq) {
+ while (tx_seq != chan->expected_tx_seq) {
control = L2CAP_SUPER_SELECT_REJECT;
- control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
l2cap_send_sframe(chan, control);
new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
- new->tx_seq = pi->expected_tx_seq;
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ new->tx_seq = chan->expected_tx_seq;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
list_add_tail(&new->list, SREJ_LIST(sk));
}
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
}
static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
@@ -3269,13 +3266,13 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
- pi->expected_ack_seq = req_seq;
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = req_seq;
+ l2cap_drop_acked_frames(chan);
- if (tx_seq == pi->expected_tx_seq)
+ if (tx_seq == chan->expected_tx_seq)
goto expected;
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
@@ -3294,14 +3291,14 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
first = list_first_entry(SREJ_LIST(sk),
struct srej_list, list);
if (tx_seq == first->tx_seq) {
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
l2cap_check_srej_gap(chan, tx_seq);
list_del(&first->list);
kfree(first);
if (list_empty(SREJ_LIST(sk))) {
- pi->buffer_seq = pi->buffer_seq_srej;
+ chan->buffer_seq = chan->buffer_seq_srej;
chan->conn_state &= ~L2CAP_CONN_SREJ_SENT;
l2cap_send_ack(chan);
BT_DBG("sk %p, Exit SREJ_SENT", sk);
@@ -3310,7 +3307,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
struct srej_list *l;
/* duplicated tx_seq */
- if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
+ if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0)
goto drop;
list_for_each_entry(l, SREJ_LIST(sk), list) {
@@ -3323,7 +3320,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
}
} else {
expected_tx_seq_offset =
- (pi->expected_tx_seq - pi->buffer_seq) % 64;
+ (chan->expected_tx_seq - chan->buffer_seq) % 64;
if (expected_tx_seq_offset < 0)
expected_tx_seq_offset += 64;
@@ -3336,11 +3333,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
BT_DBG("sk %p, Enter SREJ", sk);
INIT_LIST_HEAD(SREJ_LIST(sk));
- pi->buffer_seq_srej = pi->buffer_seq;
+ chan->buffer_seq_srej = chan->buffer_seq;
__skb_queue_head_init(SREJ_QUEUE(sk));
__skb_queue_head_init(BUSY_QUEUE(sk));
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
chan->conn_state |= L2CAP_CONN_SEND_PBIT;
@@ -3351,7 +3348,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
return 0;
expected:
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
bt_cb(skb)->tx_seq = tx_seq;
@@ -3392,8 +3389,8 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co
BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
rx_control);
- pi->expected_ack_seq = __get_reqseq(rx_control);
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = __get_reqseq(rx_control);
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL) {
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
@@ -3431,15 +3428,14 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co
static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_FINAL) {
if (chan->conn_state & L2CAP_CONN_REJ_ACT)
@@ -3463,8 +3459,8 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
if (rx_control & L2CAP_CTRL_POLL) {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
l2cap_retransmit_one_frame(chan, tx_seq);
@@ -3498,8 +3494,8 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
chan->conn_state |= L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL)
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
@@ -3585,12 +3581,12 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
}
req_seq = __get_reqseq(control);
- req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
+ req_seq_offset = (req_seq - chan->expected_ack_seq) % 64;
if (req_seq_offset < 0)
req_seq_offset += 64;
next_tx_seq_offset =
- (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+ (chan->next_tx_seq - chan->expected_ack_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
@@ -3690,10 +3686,10 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
tx_seq = __get_txseq(control);
- if (pi->expected_tx_seq == tx_seq)
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ if (chan->expected_tx_seq == tx_seq)
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
else
- pi->expected_tx_seq = (tx_seq + 1) % 64;
+ chan->expected_tx_seq = (tx_seq + 1) % 64;
l2cap_streaming_reassembly_sdu(chan, skb, control);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 66ec966..19574e4 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -777,7 +777,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
}
if (pi->mode == L2CAP_MODE_STREAMING) {
- l2cap_streaming_send(sk);
+ l2cap_streaming_send(pi->chan);
err = len;
break;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 09/15] Bluetooth: Move more ERTM stuff to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 08/15] Bluetooth: Move of ERTM *_seq vars " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 10/15] Bluetooth: Move SDU related vars " Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel stuff to l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 10 ++++----
net/bluetooth/l2cap_core.c | 51 +++++++++++++++++++---------------------
2 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 9b43874..041213b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -293,6 +293,11 @@ struct l2cap_chan {
__u8 expected_tx_seq;
__u8 buffer_seq;
__u8 buffer_seq_srej;
+ __u8 srej_save_reqseq;
+ __u8 frames_sent;
+ __u8 unacked_frames;
+ __u8 retry_count;
+ __u8 num_acked;
struct list_head list;
};
@@ -359,11 +364,6 @@ struct l2cap_pinfo {
__u8 conf_state;
- __u8 srej_save_reqseq;
- __u8 frames_sent;
- __u8 unacked_frames;
- __u8 retry_count;
- __u8 num_acked;
__u16 sdu_len;
__u16 partial_sdu_len;
struct sk_buff *sdu;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e00856d..97a6b34 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -925,7 +925,7 @@ int __l2cap_wait_ack(struct sock *sk)
int timeo = HZ/5;
add_wait_queue(sk_sleep(sk), &wait);
- while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
+ while ((l2cap_pi(sk)->chan->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo)
@@ -957,13 +957,13 @@ static void l2cap_monitor_timeout(unsigned long arg)
BT_DBG("chan %p", chan);
bh_lock_sock(sk);
- if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
+ if (chan->retry_count >= l2cap_pi(sk)->remote_max_tx) {
l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
bh_unlock_sock(sk);
return;
}
- l2cap_pi(sk)->retry_count++;
+ chan->retry_count++;
__mod_monitor_timer();
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
@@ -978,7 +978,7 @@ static void l2cap_retrans_timeout(unsigned long arg)
BT_DBG("sk %p", sk);
bh_lock_sock(sk);
- l2cap_pi(sk)->retry_count = 1;
+ chan->retry_count = 1;
__mod_monitor_timer();
chan->conn_state |= L2CAP_CONN_WAIT_F;
@@ -993,17 +993,17 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
struct sk_buff *skb;
while ((skb = skb_peek(TX_QUEUE(sk))) &&
- l2cap_pi(sk)->unacked_frames) {
+ chan->unacked_frames) {
if (bt_cb(skb)->tx_seq == chan->expected_ack_seq)
break;
skb = skb_dequeue(TX_QUEUE(sk));
kfree_skb(skb);
- l2cap_pi(sk)->unacked_frames--;
+ chan->unacked_frames--;
}
- if (!l2cap_pi(sk)->unacked_frames)
+ if (!chan->unacked_frames)
del_timer(&l2cap_pi(sk)->retrans_timer);
}
@@ -1142,9 +1142,9 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
if (bt_cb(skb)->retries == 1)
- pi->unacked_frames++;
+ chan->unacked_frames++;
- pi->frames_sent++;
+ chan->frames_sent++;
if (skb_queue_is_last(TX_QUEUE(sk), skb))
sk->sk_send_head = NULL;
@@ -1575,10 +1575,10 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
struct sock *sk = chan->sk;
chan->expected_ack_seq = 0;
- l2cap_pi(sk)->unacked_frames = 0;
+ chan->unacked_frames = 0;
chan->buffer_seq = 0;
- l2cap_pi(sk)->num_acked = 0;
- l2cap_pi(sk)->frames_sent = 0;
+ chan->num_acked = 0;
+ chan->frames_sent = 0;
setup_timer(&l2cap_pi(sk)->retrans_timer,
l2cap_retrans_timeout, (unsigned long) chan);
@@ -2788,10 +2788,9 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u16 control = 0;
- pi->frames_sent = 0;
+ chan->frames_sent = 0;
control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
@@ -2807,7 +2806,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
l2cap_ertm_send(chan);
if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
- pi->frames_sent == 0) {
+ chan->frames_sent == 0) {
control |= L2CAP_SUPER_RCV_READY;
l2cap_send_sframe(chan, control);
}
@@ -2989,7 +2988,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
l2cap_send_sframe(chan, control);
- l2cap_pi(sk)->retry_count = 1;
+ chan->retry_count = 1;
del_timer(&pi->retrans_timer);
__mod_monitor_timer();
@@ -3261,7 +3260,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
if (L2CAP_CTRL_FINAL & rx_control &&
chan->conn_state & L2CAP_CONN_WAIT_F) {
del_timer(&pi->monitor_timer);
- if (pi->unacked_frames > 0)
+ if (chan->unacked_frames > 0)
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
@@ -3370,8 +3369,8 @@ expected:
__mod_ack_timer();
- pi->num_acked = (pi->num_acked + 1) % num_to_ack;
- if (pi->num_acked == num_to_ack - 1)
+ chan->num_acked = (chan->num_acked + 1) % num_to_ack;
+ if (chan->num_acked == num_to_ack - 1)
l2cap_send_ack(chan);
return 0;
@@ -3384,7 +3383,6 @@ drop:
static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
rx_control);
@@ -3396,7 +3394,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->unacked_frames > 0))
+ (chan->unacked_frames > 0))
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
@@ -3415,7 +3413,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co
} else {
if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->unacked_frames > 0))
+ (chan->unacked_frames > 0))
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
@@ -3451,7 +3449,6 @@ static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_c
}
static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
@@ -3468,19 +3465,19 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_
l2cap_ertm_send(chan);
if (chan->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
+ chan->srej_save_reqseq = tx_seq;
chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
} else if (rx_control & L2CAP_CTRL_FINAL) {
if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) &&
- pi->srej_save_reqseq == tx_seq)
+ chan->srej_save_reqseq == tx_seq)
chan->conn_state &= ~L2CAP_CONN_SREJ_ACT;
else
l2cap_retransmit_one_frame(chan, tx_seq);
} else {
l2cap_retransmit_one_frame(chan, tx_seq);
if (chan->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
+ chan->srej_save_reqseq = tx_seq;
chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
}
@@ -3522,7 +3519,7 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont
if (L2CAP_CTRL_FINAL & rx_control &&
chan->conn_state & L2CAP_CONN_WAIT_F) {
del_timer(&l2cap_pi(sk)->monitor_timer);
- if (l2cap_pi(sk)->unacked_frames > 0)
+ if (chan->unacked_frames > 0)
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 10/15] Bluetooth: Move SDU related vars to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 09/15] Bluetooth: Move more ERTM stuff " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 11/15] Bluetooth: Move remote info " Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel stuff to l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 8 ++--
net/bluetooth/l2cap_core.c | 74 ++++++++++++++++++++--------------------
2 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 041213b..19d613b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -298,6 +298,10 @@ struct l2cap_chan {
__u8 unacked_frames;
__u8 retry_count;
__u8 num_acked;
+ __u16 sdu_len;
+ __u16 partial_sdu_len;
+ struct sk_buff *sdu;
+
struct list_head list;
};
@@ -364,10 +368,6 @@ struct l2cap_pinfo {
__u8 conf_state;
- __u16 sdu_len;
- __u16 partial_sdu_len;
- struct sk_buff *sdu;
-
__u8 tx_win;
__u8 max_tx;
__u8 remote_tx_win;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 97a6b34..9f59147 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2876,13 +2876,13 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
if (chan->conn_state & L2CAP_CONN_SAR_SDU)
goto drop;
- pi->sdu_len = get_unaligned_le16(skb->data);
+ chan->sdu_len = get_unaligned_le16(skb->data);
- if (pi->sdu_len > pi->imtu)
+ if (chan->sdu_len > pi->imtu)
goto disconnect;
- pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
- if (!pi->sdu)
+ chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
+ if (!chan->sdu)
return -ENOMEM;
/* pull sdu_len bytes only after alloc, because of Local Busy
@@ -2890,24 +2890,24 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
* only once, i.e., when alloc does not fail */
skb_pull(skb, 2);
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
chan->conn_state |= L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len = skb->len;
+ chan->partial_sdu_len = skb->len;
break;
case L2CAP_SDU_CONTINUE:
if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
- if (!pi->sdu)
+ if (!chan->sdu)
goto disconnect;
- pi->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->sdu_len)
+ chan->partial_sdu_len += skb->len;
+ if (chan->partial_sdu_len > chan->sdu_len)
goto drop;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
break;
@@ -2915,22 +2915,22 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
- if (!pi->sdu)
+ if (!chan->sdu)
goto disconnect;
if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) {
- pi->partial_sdu_len += skb->len;
+ chan->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->imtu)
+ if (chan->partial_sdu_len > pi->imtu)
goto drop;
- if (pi->partial_sdu_len != pi->sdu_len)
+ if (chan->partial_sdu_len != chan->sdu_len)
goto drop;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
}
- _skb = skb_clone(pi->sdu, GFP_ATOMIC);
+ _skb = skb_clone(chan->sdu, GFP_ATOMIC);
if (!_skb) {
chan->conn_state |= L2CAP_CONN_SAR_RETRY;
return -ENOMEM;
@@ -2946,7 +2946,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
chan->conn_state &= ~L2CAP_CONN_SAR_RETRY;
chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
@@ -2954,8 +2954,8 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
return 0;
drop:
- kfree_skb(pi->sdu);
- pi->sdu = NULL;
+ kfree_skb(chan->sdu);
+ chan->sdu = NULL;
disconnect:
l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET);
@@ -3105,7 +3105,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
switch (control & L2CAP_CTRL_SAR) {
case L2CAP_SDU_UNSEGMENTED:
if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
@@ -3117,28 +3117,28 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
case L2CAP_SDU_START:
if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
- pi->sdu_len = get_unaligned_le16(skb->data);
+ chan->sdu_len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
- if (pi->sdu_len > pi->imtu) {
+ if (chan->sdu_len > pi->imtu) {
err = -EMSGSIZE;
break;
}
- pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
- if (!pi->sdu) {
+ chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
+ if (!chan->sdu) {
err = -ENOMEM;
break;
}
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
chan->conn_state |= L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len = skb->len;
+ chan->partial_sdu_len = skb->len;
err = 0;
break;
@@ -3146,11 +3146,11 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
- pi->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->sdu_len)
- kfree_skb(pi->sdu);
+ chan->partial_sdu_len += skb->len;
+ if (chan->partial_sdu_len > chan->sdu_len)
+ kfree_skb(chan->sdu);
else
err = 0;
@@ -3160,16 +3160,16 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len += skb->len;
+ chan->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->imtu)
+ if (chan->partial_sdu_len > pi->imtu)
goto drop;
- if (pi->partial_sdu_len == pi->sdu_len) {
- _skb = skb_clone(pi->sdu, GFP_ATOMIC);
+ if (chan->partial_sdu_len == chan->sdu_len) {
+ _skb = skb_clone(chan->sdu, GFP_ATOMIC);
err = sock_queue_rcv_skb(chan->sk, _skb);
if (err < 0)
kfree_skb(_skb);
@@ -3177,7 +3177,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
err = 0;
drop:
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 11/15] Bluetooth: Move remote info to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 10/15] Bluetooth: Move SDU related vars " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 12/15] Bluetooth: Move ERTM timers " Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel stuff to l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 10 +++++-----
net/bluetooth/l2cap_core.c | 32 ++++++++++++++++----------------
net/bluetooth/l2cap_sock.c | 4 ++--
3 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 19d613b..11c53cb 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -302,6 +302,9 @@ struct l2cap_chan {
__u16 partial_sdu_len;
struct sk_buff *sdu;
+ __u8 remote_tx_win;
+ __u8 remote_max_tx;
+ __u16 remote_mps;
struct list_head list;
};
@@ -370,11 +373,8 @@ struct l2cap_pinfo {
__u8 tx_win;
__u8 max_tx;
- __u8 remote_tx_win;
- __u8 remote_max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
- __u16 remote_mps;
__u16 mps;
__le16 sport;
@@ -431,7 +431,7 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
if (sub < 0)
sub += 64;
- return sub == l2cap_pi(ch->sk)->remote_tx_win;
+ return sub == ch->remote_tx_win;
}
#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
@@ -454,7 +454,7 @@ int __l2cap_wait_ack(struct sock *sk);
struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
-int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len);
+int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
void l2cap_streaming_send(struct l2cap_chan *chan);
int l2cap_ertm_send(struct l2cap_chan *chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9f59147..512cf26 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -957,7 +957,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
BT_DBG("chan %p", chan);
bh_lock_sock(sk);
- if (chan->retry_count >= l2cap_pi(sk)->remote_max_tx) {
+ if (chan->retry_count >= chan->remote_max_tx) {
l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
bh_unlock_sock(sk);
return;
@@ -1066,8 +1066,8 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
} while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
- if (pi->remote_max_tx &&
- bt_cb(skb)->retries == pi->remote_max_tx) {
+ if (chan->remote_max_tx &&
+ bt_cb(skb)->retries == chan->remote_max_tx) {
l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
return;
}
@@ -1107,8 +1107,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) {
- if (pi->remote_max_tx &&
- bt_cb(skb)->retries == pi->remote_max_tx) {
+ if (chan->remote_max_tx &&
+ bt_cb(skb)->retries == chan->remote_max_tx) {
l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
break;
}
@@ -1338,9 +1338,9 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
return skb;
}
-int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
+int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
struct sk_buff_head sar_queue;
u16 control;
@@ -1348,20 +1348,20 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
skb_queue_head_init(&sar_queue);
control = L2CAP_SDU_START;
- skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
+ skb = l2cap_create_iframe_pdu(sk, msg, chan->remote_mps, control, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
__skb_queue_tail(&sar_queue, skb);
- len -= pi->remote_mps;
- size += pi->remote_mps;
+ len -= chan->remote_mps;
+ size += chan->remote_mps;
while (len > 0) {
size_t buflen;
- if (len > pi->remote_mps) {
+ if (len > chan->remote_mps) {
control = L2CAP_SDU_CONTINUE;
- buflen = pi->remote_mps;
+ buflen = chan->remote_mps;
} else {
control = L2CAP_SDU_END;
buflen = len;
@@ -1811,13 +1811,13 @@ done:
break;
case L2CAP_MODE_ERTM:
- pi->remote_tx_win = rfc.txwin_size;
- pi->remote_max_tx = rfc.max_transmit;
+ chan->remote_tx_win = rfc.txwin_size;
+ chan->remote_max_tx = rfc.max_transmit;
if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
- pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
rfc.retrans_timeout =
le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
@@ -1835,7 +1835,7 @@ done:
if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
- pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 19574e4..f90ca25 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -757,7 +757,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
/* Entire SDU fits into one PDU */
- if (len <= pi->remote_mps) {
+ if (len <= pi->chan->remote_mps) {
control = L2CAP_SDU_UNSEGMENTED;
skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
if (IS_ERR(skb)) {
@@ -771,7 +771,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
} else {
/* Segment SDU into multiples PDUs */
- err = l2cap_sar_segment_sdu(sk, msg, len);
+ err = l2cap_sar_segment_sdu(pi->chan, msg, len);
if (err < 0)
goto done;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 11/15] Bluetooth: Move remote info " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 13/15] Bluetooth: Move srej and busy queues " Gustavo F. Padovan
2011-04-04 21:00 ` [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan Anderson Lizardo
0 siblings, 2 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
This also triggered a change in l2cap_send_disconn_req() parameters.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 15 ++++----
net/bluetooth/l2cap_core.c | 74 ++++++++++++++++++++---------------------
net/bluetooth/l2cap_sock.c | 13 ++++---
3 files changed, 51 insertions(+), 51 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 11c53cb..5f4abea 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -306,6 +306,10 @@ struct l2cap_chan {
__u8 remote_max_tx;
__u16 remote_mps;
+ struct timer_list retrans_timer;
+ struct timer_list monitor_timer;
+ struct timer_list ack_timer;
+
struct list_head list;
};
@@ -379,9 +383,6 @@ struct l2cap_pinfo {
__le16 sport;
- struct timer_list retrans_timer;
- struct timer_list monitor_timer;
- struct timer_list ack_timer;
struct sk_buff_head tx_queue;
struct sk_buff_head srej_queue;
struct sk_buff_head busy_queue;
@@ -415,11 +416,11 @@ struct l2cap_pinfo {
#define L2CAP_CONN_RNR_SENT 0x0200
#define L2CAP_CONN_SAR_RETRY 0x0400
-#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
+#define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
-#define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \
+#define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
-#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \
+#define __mod_ack_timer() mod_timer(&chan->ack_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
@@ -466,7 +467,7 @@ void l2cap_sock_kill(struct sock *sk);
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
+void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
void l2cap_chan_del(struct l2cap_chan *chan, int err);
int l2cap_do_connect(struct sock *sk);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 512cf26..b44347b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -241,9 +241,9 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
struct srej_list *l, *tmp;
- del_timer(&l2cap_pi(sk)->retrans_timer);
- del_timer(&l2cap_pi(sk)->monitor_timer);
- del_timer(&l2cap_pi(sk)->ack_timer);
+ del_timer(&chan->retrans_timer);
+ del_timer(&chan->monitor_timer);
+ del_timer(&chan->ack_timer);
skb_queue_purge(SREJ_QUEUE(sk));
skb_queue_purge(BUSY_QUEUE(sk));
@@ -462,19 +462,22 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
}
}
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
+void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
{
+ struct sock *sk;
struct l2cap_disconn_req req;
if (!conn)
return;
+ sk = chan->sk;
+
skb_queue_purge(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
- del_timer(&l2cap_pi(sk)->retrans_timer);
- del_timer(&l2cap_pi(sk)->monitor_timer);
- del_timer(&l2cap_pi(sk)->ack_timer);
+ del_timer(&chan->retrans_timer);
+ del_timer(&chan->monitor_timer);
+ del_timer(&chan->ack_timer);
}
req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
@@ -958,7 +961,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
bh_lock_sock(sk);
if (chan->retry_count >= chan->remote_max_tx) {
- l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
+ l2cap_send_disconn_req(l2cap_pi(chan)->conn, chan, ECONNABORTED);
bh_unlock_sock(sk);
return;
}
@@ -1004,7 +1007,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
}
if (!chan->unacked_frames)
- del_timer(&l2cap_pi(sk)->retrans_timer);
+ del_timer(&chan->retrans_timer);
}
void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
@@ -1068,7 +1071,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
if (chan->remote_max_tx &&
bt_cb(skb)->retries == chan->remote_max_tx) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED);
return;
}
@@ -1109,7 +1112,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
if (chan->remote_max_tx &&
bt_cb(skb)->retries == chan->remote_max_tx) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED);
break;
}
@@ -1580,12 +1583,11 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
chan->num_acked = 0;
chan->frames_sent = 0;
- setup_timer(&l2cap_pi(sk)->retrans_timer,
- l2cap_retrans_timeout, (unsigned long) chan);
- setup_timer(&l2cap_pi(sk)->monitor_timer,
- l2cap_monitor_timeout, (unsigned long) chan);
- setup_timer(&l2cap_pi(sk)->ack_timer,
- l2cap_ack_timeout, (unsigned long) chan);
+ setup_timer(&chan->retrans_timer, l2cap_retrans_timeout,
+ (unsigned long) chan);
+ setup_timer(&chan->monitor_timer, l2cap_monitor_timeout,
+ (unsigned long) chan);
+ setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan);
__skb_queue_head_init(SREJ_QUEUE(sk));
__skb_queue_head_init(BUSY_QUEUE(sk));
@@ -2292,7 +2294,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* Complete config. */
len = l2cap_parse_conf_req(chan, rsp);
if (len < 0) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto unlock;
}
@@ -2364,7 +2366,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -2373,7 +2375,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
len = l2cap_parse_conf_rsp(sk, rsp->data,
len, req, &result);
if (len < 0) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -2388,7 +2390,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default:
sk->sk_err = ECONNRESET;
l2cap_sock_set_timer(sk, HZ * 5);
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -2958,7 +2960,7 @@ drop:
chan->sdu = NULL;
disconnect:
- l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
kfree_skb(skb);
return 0;
}
@@ -2966,7 +2968,6 @@ disconnect:
static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb;
u16 control;
int err;
@@ -2990,7 +2991,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
l2cap_send_sframe(chan, control);
chan->retry_count = 1;
- del_timer(&pi->retrans_timer);
+ del_timer(&chan->retrans_timer);
__mod_monitor_timer();
chan->conn_state |= L2CAP_CONN_WAIT_F;
@@ -3021,7 +3022,7 @@ static void l2cap_busy_work(struct work_struct *work)
if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
err = -EBUSY;
- l2cap_send_disconn_req(pi->conn, sk, EBUSY);
+ l2cap_send_disconn_req(pi->conn, pi->chan, EBUSY);
break;
}
@@ -3084,7 +3085,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
chan->conn_state |= L2CAP_CONN_RNR_SENT;
- del_timer(&pi->ack_timer);
+ del_timer(&chan->ack_timer);
queue_work(_busy_wq, &pi->busy_work);
@@ -3259,7 +3260,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
if (L2CAP_CTRL_FINAL & rx_control &&
chan->conn_state & L2CAP_CONN_WAIT_F) {
- del_timer(&pi->monitor_timer);
+ del_timer(&chan->monitor_timer);
if (chan->unacked_frames > 0)
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
@@ -3277,7 +3278,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
/* invalid tx_seq */
if (tx_seq_offset >= pi->tx_win) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
goto drop;
}
@@ -3342,7 +3343,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
l2cap_send_srejframe(chan, tx_seq);
- del_timer(&pi->ack_timer);
+ del_timer(&chan->ack_timer);
}
return 0;
@@ -3485,7 +3486,6 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_
static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
@@ -3498,7 +3498,7 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) {
- del_timer(&pi->retrans_timer);
+ del_timer(&chan->retrans_timer);
if (rx_control & L2CAP_CTRL_POLL)
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL);
return;
@@ -3512,13 +3512,11 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c
static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
- struct sock *sk = chan->sk;
-
BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len);
if (L2CAP_CTRL_FINAL & rx_control &&
chan->conn_state & L2CAP_CONN_WAIT_F) {
- del_timer(&l2cap_pi(sk)->monitor_timer);
+ del_timer(&chan->monitor_timer);
if (chan->unacked_frames > 0)
__mod_retrans_timer();
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
@@ -3573,7 +3571,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
len -= 2;
if (len > pi->mps) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
goto drop;
}
@@ -3589,13 +3587,13 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
/* check for invalid req-seq */
if (req_seq_offset > next_tx_seq_offset) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
goto drop;
}
if (__is_iframe(control)) {
if (len < 0) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
goto drop;
}
@@ -3603,7 +3601,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
} else {
if (len != 0) {
BT_ERR("%d", len);
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
goto drop;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f90ca25..d66886f 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -866,6 +866,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
void __l2cap_sock_close(struct sock *sk, int reason)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
@@ -880,9 +881,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
sk->sk_type == SOCK_STREAM) &&
conn->hcon->type == ACL_LINK) {
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
- l2cap_send_disconn_req(conn, sk, reason);
+ l2cap_send_disconn_req(conn, chan, reason);
} else
- l2cap_chan_del(l2cap_pi(sk)->chan, reason);
+ l2cap_chan_del(chan, reason);
break;
case BT_CONNECT2:
@@ -901,16 +902,16 @@ void __l2cap_sock_close(struct sock *sk, int reason)
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, l2cap_pi(sk)->chan->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
}
- l2cap_chan_del(l2cap_pi(sk)->chan, reason);
+ l2cap_chan_del(chan, reason);
break;
case BT_CONNECT:
case BT_DISCONN:
- l2cap_chan_del(l2cap_pi(sk)->chan, reason);
+ l2cap_chan_del(chan, reason);
break;
default:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 13/15] Bluetooth: Move srej and busy queues to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 12/15] Bluetooth: Move ERTM timers " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 14/15] Bluetooth: Move busy workqueue " Gustavo F. Padovan
2011-04-04 21:00 ` [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan Anderson Lizardo
1 sibling, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel stuff to l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 6 +---
net/bluetooth/l2cap_core.c | 42 +++++++++++++++++++---------------------
net/bluetooth/l2cap_sock.c | 2 -
3 files changed, 22 insertions(+), 28 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 5f4abea..09f4a2f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -309,6 +309,8 @@ struct l2cap_chan {
struct timer_list retrans_timer;
struct timer_list monitor_timer;
struct timer_list ack_timer;
+ struct sk_buff_head srej_q;
+ struct sk_buff_head busy_q;
struct list_head list;
};
@@ -347,8 +349,6 @@ struct l2cap_conn {
/* ----- L2CAP socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
-#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
-#define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue)
#define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)
struct srej_list {
@@ -384,8 +384,6 @@ struct l2cap_pinfo {
__le16 sport;
struct sk_buff_head tx_queue;
- struct sk_buff_head srej_queue;
- struct sk_buff_head busy_queue;
struct work_struct busy_work;
struct srej_list srej_l;
struct l2cap_conn *conn;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b44347b..a5aecc5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -245,8 +245,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
del_timer(&chan->monitor_timer);
del_timer(&chan->ack_timer);
- skb_queue_purge(SREJ_QUEUE(sk));
- skb_queue_purge(BUSY_QUEUE(sk));
+ skb_queue_purge(&chan->srej_q);
+ skb_queue_purge(&chan->busy_q);
list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
list_del(&l->list);
@@ -1589,8 +1589,8 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
(unsigned long) chan);
setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan);
- __skb_queue_head_init(SREJ_QUEUE(sk));
- __skb_queue_head_init(BUSY_QUEUE(sk));
+ skb_queue_head_init(&chan->srej_q);
+ skb_queue_head_init(&chan->busy_q);
INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
@@ -2816,16 +2816,15 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
- struct sock *sk = chan->sk;
struct sk_buff *next_skb;
int tx_seq_offset, next_tx_seq_offset;
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
- next_skb = skb_peek(SREJ_QUEUE(sk));
+ next_skb = skb_peek(&chan->srej_q);
if (!next_skb) {
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
@@ -2843,16 +2842,16 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
next_tx_seq_offset += 64;
if (next_tx_seq_offset > tx_seq_offset) {
- __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
+ __skb_queue_before(&chan->srej_q, next_skb, skb);
return 0;
}
- if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
+ if (skb_queue_is_last(&chan->srej_q, next_skb))
break;
- } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
+ } while ((next_skb = skb_queue_next(&chan->srej_q, next_skb)));
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
@@ -2972,11 +2971,11 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
u16 control;
int err;
- while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
+ while ((skb = skb_dequeue(&chan->busy_q))) {
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err < 0) {
- skb_queue_head(BUSY_QUEUE(sk), skb);
+ skb_queue_head(&chan->busy_q, skb);
return -EBUSY;
}
@@ -3017,7 +3016,7 @@ static void l2cap_busy_work(struct work_struct *work)
lock_sock(sk);
add_wait_queue(sk_sleep(sk), &wait);
- while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
+ while ((skb = skb_peek(&pi->chan->busy_q))) {
set_current_state(TASK_INTERRUPTIBLE);
if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
@@ -3060,7 +3059,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
- __skb_queue_tail(BUSY_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->busy_q, skb);
return l2cap_try_push_rx_skb(chan);
@@ -3077,7 +3076,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
chan->conn_state |= L2CAP_CONN_LOCAL_BUSY;
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
- __skb_queue_tail(BUSY_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->busy_q, skb);
sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
sctrl |= L2CAP_SUPER_RCV_NOT_READY;
@@ -3188,15 +3187,14 @@ drop:
static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
{
- struct sock *sk = chan->sk;
struct sk_buff *skb;
u16 control;
- while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
+ while ((skb = skb_peek(&chan->srej_q))) {
if (bt_cb(skb)->tx_seq != tx_seq)
break;
- skb = skb_dequeue(SREJ_QUEUE(sk));
+ skb = skb_dequeue(&chan->srej_q);
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
l2cap_ertm_reassembly_sdu(chan, skb, control);
chan->buffer_seq_srej =
@@ -3335,8 +3333,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
INIT_LIST_HEAD(SREJ_LIST(sk));
chan->buffer_seq_srej = chan->buffer_seq;
- __skb_queue_head_init(SREJ_QUEUE(sk));
- __skb_queue_head_init(BUSY_QUEUE(sk));
+ __skb_queue_head_init(&chan->srej_q);
+ __skb_queue_head_init(&chan->busy_q);
l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
chan->conn_state |= L2CAP_CONN_SEND_PBIT;
@@ -3353,7 +3351,7 @@ expected:
if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index d66886f..55dee99 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1018,8 +1018,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
/* Default config options */
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
skb_queue_head_init(TX_QUEUE(sk));
- skb_queue_head_init(SREJ_QUEUE(sk));
- skb_queue_head_init(BUSY_QUEUE(sk));
INIT_LIST_HEAD(SREJ_LIST(sk));
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 14/15] Bluetooth: Move busy workqueue to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 13/15] Bluetooth: Move srej and busy queues " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 15/15] Bluetooth: Fix lockdep warning with skb list lock Gustavo F. Padovan
0 siblings, 1 reply; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
As part of the moving channel stuff to l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 2 +-
net/bluetooth/l2cap_core.c | 20 +++++++++-----------
2 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 09f4a2f..d05d91f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -311,6 +311,7 @@ struct l2cap_chan {
struct timer_list ack_timer;
struct sk_buff_head srej_q;
struct sk_buff_head busy_q;
+ struct work_struct busy_work;
struct list_head list;
};
@@ -384,7 +385,6 @@ struct l2cap_pinfo {
__le16 sport;
struct sk_buff_head tx_queue;
- struct work_struct busy_work;
struct srej_list srej_l;
struct l2cap_conn *conn;
struct l2cap_chan *chan;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a5aecc5..0cf3a55 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1592,7 +1592,7 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
skb_queue_head_init(&chan->srej_q);
skb_queue_head_init(&chan->busy_q);
- INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
+ INIT_WORK(&chan->busy_work, l2cap_busy_work);
sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
}
@@ -3007,21 +3007,21 @@ done:
static void l2cap_busy_work(struct work_struct *work)
{
DECLARE_WAITQUEUE(wait, current);
- struct l2cap_pinfo *pi =
- container_of(work, struct l2cap_pinfo, busy_work);
- struct sock *sk = (struct sock *)pi;
+ struct l2cap_chan *chan =
+ container_of(work, struct l2cap_chan, busy_work);
+ struct sock *sk = chan->sk;
int n_tries = 0, timeo = HZ/5, err;
struct sk_buff *skb;
lock_sock(sk);
add_wait_queue(sk_sleep(sk), &wait);
- while ((skb = skb_peek(&pi->chan->busy_q))) {
+ while ((skb = skb_peek(&chan->busy_q))) {
set_current_state(TASK_INTERRUPTIBLE);
if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
err = -EBUSY;
- l2cap_send_disconn_req(pi->conn, pi->chan, EBUSY);
+ l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, EBUSY);
break;
}
@@ -3041,7 +3041,7 @@ static void l2cap_busy_work(struct work_struct *work)
if (err)
break;
- if (l2cap_try_push_rx_skb(l2cap_pi(sk)->chan) == 0)
+ if (l2cap_try_push_rx_skb(chan) == 0)
break;
}
@@ -3053,8 +3053,6 @@ static void l2cap_busy_work(struct work_struct *work)
static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int sctrl, err;
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
@@ -3072,7 +3070,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
}
/* Busy Condition */
- BT_DBG("sk %p, Enter local busy", sk);
+ BT_DBG("chan %p, Enter local busy", chan);
chan->conn_state |= L2CAP_CONN_LOCAL_BUSY;
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
@@ -3086,7 +3084,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
del_timer(&chan->ack_timer);
- queue_work(_busy_wq, &pi->busy_work);
+ queue_work(_busy_wq, &chan->busy_work);
return err;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 15/15] Bluetooth: Fix lockdep warning with skb list lock
2011-04-01 22:33 ` [PATCH 14/15] Bluetooth: Move busy workqueue " Gustavo F. Padovan
@ 2011-04-01 22:33 ` Gustavo F. Padovan
0 siblings, 0 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-01 22:33 UTC (permalink / raw)
To: linux-bluetooth
This is a regression acctually, caused by the first patch series for
creating a formal strcut l2cap_chan.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap_core.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0cf3a55..0dd8d5b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -236,6 +236,10 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
} else
sk->sk_state_change(sk);
+ if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE &&
+ l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE))
+ goto free;
+
skb_queue_purge(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
@@ -254,6 +258,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
}
}
+free:
kfree(chan);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 01/15] Bluetooth: Create struct l2cap_chan
2011-04-01 22:33 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Gustavo F. Padovan
@ 2011-04-04 19:22 ` Anderson Lizardo
2011-04-04 20:07 ` Gustavo F. Padovan
1 sibling, 1 reply; 23+ messages in thread
From: Anderson Lizardo @ 2011-04-04 19:22 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
Hi Gustavo,
On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> @@ -203,13 +217,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
> l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
> }
>
> - __l2cap_chan_link(l, sk);
> + __l2cap_chan_link(l, chan);
> }
>
> /* Delete channel.
> * Must be called on the locked socket. */
> -void l2cap_chan_del(struct sock *sk, int err)
> +void l2cap_chan_del(struct l2cap_chan *chan, int err)
> {
> + struct sock *sk = chan->sk;
> struct l2cap_conn *conn = l2cap_pi(sk)->conn;
> struct sock *parent = bt_sk(sk)->parent;
>
> @@ -219,7 +234,7 @@ void l2cap_chan_del(struct sock *sk, int err)
>
> if (conn) {
> /* Unlink from channel list */
> - l2cap_chan_unlink(&conn->chan_list, sk);
> + l2cap_chan_unlink(&conn->chan_list, chan);
> l2cap_pi(sk)->conn = NULL;
> hci_conn_put(conn->hcon);
> }
> @@ -253,6 +268,8 @@ void l2cap_chan_del(struct sock *sk, int err)
> kfree(l);
> }
> }
> +
> + kfree(chan);
Just wondering: isn't also necessary to do "l2cap_pi(sk)->chan =
NULL;" here, supposing the underlying struct sock will still be
allocated?
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 01/15] Bluetooth: Create struct l2cap_chan
2011-04-04 19:22 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Anderson Lizardo
@ 2011-04-04 20:07 ` Gustavo F. Padovan
0 siblings, 0 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-04 20:07 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
Hi Lizardo.
* Anderson Lizardo <anderson.lizardo@openbossa.org> [2011-04-04 15:22:29 -0400]:
> Hi Gustavo,
>
> On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > @@ -203,13 +217,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
> > l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
> > }
> >
> > - __l2cap_chan_link(l, sk);
> > + __l2cap_chan_link(l, chan);
> > }
> >
> > /* Delete channel.
> > * Must be called on the locked socket. */
> > -void l2cap_chan_del(struct sock *sk, int err)
> > +void l2cap_chan_del(struct l2cap_chan *chan, int err)
> > {
> > + struct sock *sk = chan->sk;
> > struct l2cap_conn *conn = l2cap_pi(sk)->conn;
> > struct sock *parent = bt_sk(sk)->parent;
> >
> > @@ -219,7 +234,7 @@ void l2cap_chan_del(struct sock *sk, int err)
> >
> > if (conn) {
> > /* Unlink from channel list */
> > - l2cap_chan_unlink(&conn->chan_list, sk);
> > + l2cap_chan_unlink(&conn->chan_list, chan);
> > l2cap_pi(sk)->conn = NULL;
> > hci_conn_put(conn->hcon);
> > }
> > @@ -253,6 +268,8 @@ void l2cap_chan_del(struct sock *sk, int err)
> > kfree(l);
> > }
> > }
> > +
> > + kfree(chan);
>
> Just wondering: isn't also necessary to do "l2cap_pi(sk)->chan =
> NULL;" here, supposing the underlying struct sock will still be
> allocated?
No, it is always allocated. Just check the the comment on the top of the
function "Must be called on the locked socket" or the code itself.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list
2011-04-01 22:33 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 03/15] Bluetooth: Remove struct del_list Gustavo F. Padovan
@ 2011-04-04 20:28 ` Anderson Lizardo
1 sibling, 0 replies; 23+ messages in thread
From: Anderson Lizardo @ 2011-04-04 20:28 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
Hi Gustavo,
On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> @@ -724,26 +709,27 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
> bh_unlock_sock(sk);
> }
>
> - read_unlock(&l->lock);
> + read_unlock(&conn->chan_lock);
> }
>
> /* Notify sockets that we cannot guaranty reliability anymore */
> static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
> {
> - struct l2cap_chan_list *l = &conn->chan_list;
> struct l2cap_chan *chan;
> + struct sock *sk;
You can move this declaration to the list_for_each_entry() block
(like you did in other places).
>
> BT_DBG("conn %p", conn);
>
> - read_lock(&l->lock);
> + read_lock(&conn->chan_lock);
> +
> + list_for_each_entry(chan, &conn->chan_l, list) {
> + sk = chan->sk;
>
> - for (chan = l->head; chan; chan = chan->next_c) {
> - struct sock *sk = chan->sk;
> if (l2cap_pi(sk)->force_reliable)
> sk->sk_err = err;
> }
>
> - read_unlock(&l->lock);
> + read_unlock(&conn->chan_lock);
> }
>
> static void l2cap_info_timeout(unsigned long arg)
> @@ -783,7 +769,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
> conn->feat_mask = 0;
>
> spin_lock_init(&conn->lock);
> - rwlock_init(&conn->chan_list.lock);
> + rwlock_init(&conn->chan_lock);
> +
> + INIT_LIST_HEAD(&conn->chan_l);
>
> if (hcon->type != LE_LINK)
> setup_timer(&conn->info_timer, l2cap_info_timeout,
> @@ -797,7 +785,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
> static void l2cap_conn_del(struct hci_conn *hcon, int err)
> {
> struct l2cap_conn *conn = hcon->l2cap_data;
> - struct l2cap_chan *chan;
> + struct l2cap_chan *chan, *l;
> struct sock *sk;
>
> if (!conn)
> @@ -808,7 +796,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
> kfree_skb(conn->rx_skb);
>
> /* Kill channels */
> - while ((chan = conn->chan_list.head)) {
> + list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
> sk = chan->sk;
> bh_lock_sock(sk);
> l2cap_chan_del(chan, err);
> @@ -825,10 +813,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
>
> static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
> {
> - struct l2cap_chan_list *l = &conn->chan_list;
> - write_lock_bh(&l->lock);
> + write_lock_bh(&conn->chan_lock);
> __l2cap_chan_add(conn, chan);
> - write_unlock_bh(&l->lock);
> + write_unlock_bh(&conn->chan_lock);
> }
>
> /* ---- Socket interface ---- */
> @@ -1426,14 +1413,13 @@ static void l2cap_chan_ready(struct sock *sk)
> /* Copy frame to all raw sockets on that connection */
> static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> {
> - struct l2cap_chan_list *l = &conn->chan_list;
> struct sk_buff *nskb;
> struct l2cap_chan *chan;
>
> BT_DBG("conn %p", conn);
>
> - read_lock(&l->lock);
> - for (chan = l->head; chan; chan = chan->next_c) {
> + read_lock(&conn->chan_lock);
> + list_for_each_entry(chan, &conn->chan_l, list) {
> struct sock *sk = chan->sk;
> if (sk->sk_type != SOCK_RAW)
> continue;
> @@ -1448,7 +1434,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> if (sock_queue_rcv_skb(sk, nskb))
> kfree_skb(nskb);
> }
> - read_unlock(&l->lock);
> + read_unlock(&conn->chan_lock);
> }
>
> /* ---- L2CAP signalling commands ---- */
> @@ -2015,7 +2001,6 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
>
> static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
> {
> - struct l2cap_chan_list *list = &conn->chan_list;
> struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
> struct l2cap_conn_rsp rsp;
> struct l2cap_chan *chan;
> @@ -2062,11 +2047,11 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
> goto response;
> }
>
> - write_lock_bh(&list->lock);
> + write_lock_bh(&conn->chan_lock);
>
> /* Check if we already have channel with that dcid */
> - if (__l2cap_get_chan_by_dcid(list, scid)) {
> - write_unlock_bh(&list->lock);
> + if (__l2cap_get_chan_by_dcid(conn, scid)) {
> + write_unlock_bh(&conn->chan_lock);
> sock_set_flag(sk, SOCK_ZAPPED);
> l2cap_sock_kill(sk);
> goto response;
> @@ -2115,7 +2100,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
> status = L2CAP_CS_NO_INFO;
> }
>
> - write_unlock_bh(&list->lock);
> + write_unlock_bh(&conn->chan_lock);
>
> response:
> bh_unlock_sock(parent);
> @@ -2169,11 +2154,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
> BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
>
> if (scid) {
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
> + chan = l2cap_get_chan_by_scid(conn, scid);
> if (!chan)
> return -EFAULT;
> } else {
> - chan = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
> + chan = l2cap_get_chan_by_ident(conn, cmd->ident);
> if (!chan)
> return -EFAULT;
> }
> @@ -2243,7 +2228,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
>
> BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
> + chan = l2cap_get_chan_by_scid(conn, dcid);
> if (!chan)
> return -ENOENT;
>
> @@ -2338,7 +2323,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
> BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
> scid, flags, result);
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
> + chan = l2cap_get_chan_by_scid(conn, scid);
> if (!chan)
> return 0;
>
> @@ -2418,7 +2403,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
>
> BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
> + chan = l2cap_get_chan_by_scid(conn, dcid);
> if (!chan)
> return 0;
>
> @@ -2458,7 +2443,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
>
> BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid);
> + chan = l2cap_get_chan_by_scid(conn, scid);
> if (!chan)
> return 0;
>
> @@ -3612,7 +3597,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
> u8 tx_seq;
> int len;
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
> + chan = l2cap_get_chan_by_scid(conn, cid);
> if (!chan) {
> BT_DBG("unknown cid 0x%4.4x", cid);
> goto drop;
> @@ -3855,21 +3840,20 @@ static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
>
> static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
> {
> - struct l2cap_chan_list *l;
> struct l2cap_conn *conn = hcon->l2cap_data;
> struct l2cap_chan *chan;
> + struct sock *sk;
Same here.
>
> if (!conn)
> return 0;
>
> - l = &conn->chan_list;
> -
> BT_DBG("conn %p", conn);
>
> - read_lock(&l->lock);
> + read_lock(&conn->chan_lock);
> +
> + list_for_each_entry(chan, &conn->chan_l, list) {
> + sk = chan->sk;
>
> - for (chan = l->head; chan; chan = chan->next_c) {
> - struct sock *sk = chan->sk;
> bh_lock_sock(sk);
>
> if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
> @@ -3923,7 +3907,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
> bh_unlock_sock(sk);
> }
>
> - read_unlock(&l->lock);
> + read_unlock(&conn->chan_lock);
>
> return 0;
> }
> @@ -3980,7 +3964,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
> goto drop;
> }
>
> - chan = l2cap_get_chan_by_scid(&conn->chan_list, cid);
> + chan = l2cap_get_chan_by_scid(conn, cid);
>
> if (chan && chan->sk) {
> struct sock *sk = chan->sk;
> @@ -3996,6 +3980,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
> bh_unlock_sock(sk);
> }
>
> +
Unnecessary empty line.
> /* Allocate skb for the complete frame (with header) */
> conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
> if (!conn->rx_skb)
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 08/15] Bluetooth: Move of ERTM *_seq vars " Gustavo F. Padovan
@ 2011-04-04 20:50 ` Anderson Lizardo
2011-04-04 20:58 ` Gustavo F. Padovan
1 sibling, 1 reply; 23+ messages in thread
From: Anderson Lizardo @ 2011-04-04 20:50 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
Hi Gustavo,
(patch too big for me to review properly...)
On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> static void l2cap_retrans_timeout(unsigned long arg)
> {
> - struct sock *sk = (void *) arg;
> + struct l2cap_chan *chan = (void *) arg;
> + struct sock *sk = chan->sk;
>
> BT_DBG("sk %p", sk);
>
> @@ -978,9 +983,9 @@ static void l2cap_retrans_timeout(unsigned long arg)
> l2cap_pi(sk)->retry_count = 1;
> __mod_monitor_timer();
>
> - l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
> + chan->conn_state |= L2CAP_CONN_WAIT_F;
I suppose the above requires a lock ?
In general it seems that by creating the additional "l2cap_chan"
layer, all lock usages need to be reviewed (IMHO).
>
> - l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
> + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
> bh_unlock_sock(sk);
> }
>
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan
2011-04-04 20:50 ` [PATCH 07/15] Bluetooth: Move conn_state " Anderson Lizardo
@ 2011-04-04 20:58 ` Gustavo F. Padovan
0 siblings, 0 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-04 20:58 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
Hi Lizardo,
* Anderson Lizardo <anderson.lizardo@openbossa.org> [2011-04-04 16:50:13 -0400]:
> Hi Gustavo,
>
> (patch too big for me to review properly...)
>
> On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > static void l2cap_retrans_timeout(unsigned long arg)
> > {
> > - struct sock *sk = (void *) arg;
> > + struct l2cap_chan *chan = (void *) arg;
> > + struct sock *sk = chan->sk;
> >
> > BT_DBG("sk %p", sk);
> >
> > @@ -978,9 +983,9 @@ static void l2cap_retrans_timeout(unsigned long arg)
> > l2cap_pi(sk)->retry_count = 1;
> > __mod_monitor_timer();
> >
> > - l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
> > + chan->conn_state |= L2CAP_CONN_WAIT_F;
>
> I suppose the above requires a lock ?
It has one, the socket lock. It's completely safe use it here.
>
> In general it seems that by creating the additional "l2cap_chan"
> layer, all lock usages need to be reviewed (IMHO).
Yes, that will be done in an next step. I'm going to remove any sock reference
from l2cap_core.c, so a new locking system will be needed.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan
2011-04-01 22:33 ` [PATCH 12/15] Bluetooth: Move ERTM timers " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 13/15] Bluetooth: Move srej and busy queues " Gustavo F. Padovan
@ 2011-04-04 21:00 ` Anderson Lizardo
2011-04-04 21:05 ` Gustavo F. Padovan
1 sibling, 1 reply; 23+ messages in thread
From: Anderson Lizardo @ 2011-04-04 21:00 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
Hi Gustavo,
On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> @@ -958,7 +961,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
>
> bh_lock_sock(sk);
> if (chan->retry_count >= chan->remote_max_tx) {
> - l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
> + l2cap_send_disconn_req(l2cap_pi(chan)->conn, chan, ECONNABORTED);
> bh_unlock_sock(sk);
> return;
> }
Why "l2cap_pi(chan)" ? This looks strange.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan
2011-04-04 21:00 ` [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan Anderson Lizardo
@ 2011-04-04 21:05 ` Gustavo F. Padovan
0 siblings, 0 replies; 23+ messages in thread
From: Gustavo F. Padovan @ 2011-04-04 21:05 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
Hi Lizardo,
* Anderson Lizardo <anderson.lizardo@openbossa.org> [2011-04-04 17:00:17 -0400]:
> Hi Gustavo,
>
> On Fri, Apr 1, 2011 at 6:33 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > @@ -958,7 +961,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
> >
> > bh_lock_sock(sk);
> > if (chan->retry_count >= chan->remote_max_tx) {
> > - l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
> > + l2cap_send_disconn_req(l2cap_pi(chan)->conn, chan, ECONNABORTED);
> > bh_unlock_sock(sk);
> > return;
> > }
>
> Why "l2cap_pi(chan)" ? This looks strange.
Indeed, I'll fix it.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2011-04-04 21:05 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-01 22:33 [PATCH 00/15] L2CAP Rewrite (or create proper struct l2cap_chan) Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 03/15] Bluetooth: Remove struct del_list Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 04/15] Bluetooth: Move ident to struct l2cap_chan Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 05/15] Bluetooth: Move conf_{req,rsp} stuff " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 06/15] Bluetooth: clean up l2cap_sock_recvmsg() Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 07/15] Bluetooth: Move conn_state to struct l2cap_chan Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 08/15] Bluetooth: Move of ERTM *_seq vars " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 09/15] Bluetooth: Move more ERTM stuff " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 10/15] Bluetooth: Move SDU related vars " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 11/15] Bluetooth: Move remote info " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 12/15] Bluetooth: Move ERTM timers " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 13/15] Bluetooth: Move srej and busy queues " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 14/15] Bluetooth: Move busy workqueue " Gustavo F. Padovan
2011-04-01 22:33 ` [PATCH 15/15] Bluetooth: Fix lockdep warning with skb list lock Gustavo F. Padovan
2011-04-04 21:00 ` [PATCH 12/15] Bluetooth: Move ERTM timers to struct l2cap_chan Anderson Lizardo
2011-04-04 21:05 ` Gustavo F. Padovan
2011-04-04 20:50 ` [PATCH 07/15] Bluetooth: Move conn_state " Anderson Lizardo
2011-04-04 20:58 ` Gustavo F. Padovan
2011-04-04 20:28 ` [PATCH 02/15] Bluetooth: Use struct list_head for L2CAP channels list Anderson Lizardo
2011-04-04 19:22 ` [PATCH 01/15] Bluetooth: Create struct l2cap_chan Anderson Lizardo
2011-04-04 20:07 ` Gustavo F. Padovan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).