aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/l2cap.h13
-rw-r--r--net/bluetooth/l2cap_core.c22
-rw-r--r--net/bluetooth/l2cap_sock.c1
3 files changed, 17 insertions, 19 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d05d91f2fd32..ec56d8861a4e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -277,6 +277,11 @@ struct l2cap_conn_param_update_rsp {
277#define L2CAP_CONN_PARAM_REJECTED 0x0001 277#define L2CAP_CONN_PARAM_REJECTED 0x0001
278 278
279/* ----- L2CAP channels and connections ----- */ 279/* ----- L2CAP channels and connections ----- */
280struct srej_list {
281 __u8 tx_seq;
282 struct list_head list;
283};
284
280struct l2cap_chan { 285struct l2cap_chan {
281 struct sock *sk; 286 struct sock *sk;
282 __u8 ident; 287 __u8 ident;
@@ -312,6 +317,7 @@ struct l2cap_chan {
312 struct sk_buff_head srej_q; 317 struct sk_buff_head srej_q;
313 struct sk_buff_head busy_q; 318 struct sk_buff_head busy_q;
314 struct work_struct busy_work; 319 struct work_struct busy_work;
320 struct list_head srej_l;
315 321
316 struct list_head list; 322 struct list_head list;
317}; 323};
@@ -350,12 +356,6 @@ struct l2cap_conn {
350/* ----- L2CAP socket info ----- */ 356/* ----- L2CAP socket info ----- */
351#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) 357#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
352#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) 358#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
353#define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)
354
355struct srej_list {
356 __u8 tx_seq;
357 struct list_head list;
358};
359 359
360struct l2cap_pinfo { 360struct l2cap_pinfo {
361 struct bt_sock bt; 361 struct bt_sock bt;
@@ -385,7 +385,6 @@ struct l2cap_pinfo {
385 __le16 sport; 385 __le16 sport;
386 386
387 struct sk_buff_head tx_queue; 387 struct sk_buff_head tx_queue;
388 struct srej_list srej_l;
389 struct l2cap_conn *conn; 388 struct l2cap_conn *conn;
390 struct l2cap_chan *chan; 389 struct l2cap_chan *chan;
391}; 390};
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7264119b64a6..9580d6cd55da 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -252,7 +252,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
252 skb_queue_purge(&chan->srej_q); 252 skb_queue_purge(&chan->srej_q);
253 skb_queue_purge(&chan->busy_q); 253 skb_queue_purge(&chan->busy_q);
254 254
255 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { 255 list_for_each_entry_safe(l, tmp, &chan->srej_l, list) {
256 list_del(&l->list); 256 list_del(&l->list);
257 kfree(l); 257 kfree(l);
258 } 258 }
@@ -1205,7 +1205,7 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)
1205 control = L2CAP_SUPER_SELECT_REJECT; 1205 control = L2CAP_SUPER_SELECT_REJECT;
1206 control |= L2CAP_CTRL_FINAL; 1206 control |= L2CAP_CTRL_FINAL;
1207 1207
1208 tail = list_entry(SREJ_LIST(chan->sk)->prev, struct srej_list, list); 1208 tail = list_entry((&chan->srej_l)->prev, struct srej_list, list);
1209 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 1209 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1210 1210
1211 l2cap_send_sframe(chan, control); 1211 l2cap_send_sframe(chan, control);
@@ -1596,6 +1596,8 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
1596 skb_queue_head_init(&chan->srej_q); 1596 skb_queue_head_init(&chan->srej_q);
1597 skb_queue_head_init(&chan->busy_q); 1597 skb_queue_head_init(&chan->busy_q);
1598 1598
1599 INIT_LIST_HEAD(&chan->srej_l);
1600
1599 INIT_WORK(&chan->busy_work, l2cap_busy_work); 1601 INIT_WORK(&chan->busy_work, l2cap_busy_work);
1600 1602
1601 sk->sk_backlog_rcv = l2cap_ertm_data_rcv; 1603 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
@@ -3207,11 +3209,10 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
3207 3209
3208static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) 3210static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3209{ 3211{
3210 struct sock *sk = chan->sk;
3211 struct srej_list *l, *tmp; 3212 struct srej_list *l, *tmp;
3212 u16 control; 3213 u16 control;
3213 3214
3214 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { 3215 list_for_each_entry_safe(l, tmp, &chan->srej_l, list) {
3215 if (l->tx_seq == tx_seq) { 3216 if (l->tx_seq == tx_seq) {
3216 list_del(&l->list); 3217 list_del(&l->list);
3217 kfree(l); 3218 kfree(l);
@@ -3221,13 +3222,12 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3221 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3222 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3222 l2cap_send_sframe(chan, control); 3223 l2cap_send_sframe(chan, control);
3223 list_del(&l->list); 3224 list_del(&l->list);
3224 list_add_tail(&l->list, SREJ_LIST(sk)); 3225 list_add_tail(&l->list, &chan->srej_l);
3225 } 3226 }
3226} 3227}
3227 3228
3228static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) 3229static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3229{ 3230{
3230 struct sock *sk = chan->sk;
3231 struct srej_list *new; 3231 struct srej_list *new;
3232 u16 control; 3232 u16 control;
3233 3233
@@ -3239,7 +3239,7 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3239 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); 3239 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3240 new->tx_seq = chan->expected_tx_seq; 3240 new->tx_seq = chan->expected_tx_seq;
3241 chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; 3241 chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
3242 list_add_tail(&new->list, SREJ_LIST(sk)); 3242 list_add_tail(&new->list, &chan->srej_l);
3243 } 3243 }
3244 chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; 3244 chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
3245} 3245}
@@ -3288,7 +3288,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
3288 if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { 3288 if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
3289 struct srej_list *first; 3289 struct srej_list *first;
3290 3290
3291 first = list_first_entry(SREJ_LIST(sk), 3291 first = list_first_entry(&chan->srej_l,
3292 struct srej_list, list); 3292 struct srej_list, list);
3293 if (tx_seq == first->tx_seq) { 3293 if (tx_seq == first->tx_seq) {
3294 l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); 3294 l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
@@ -3297,7 +3297,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
3297 list_del(&first->list); 3297 list_del(&first->list);
3298 kfree(first); 3298 kfree(first);
3299 3299
3300 if (list_empty(SREJ_LIST(sk))) { 3300 if (list_empty(&chan->srej_l)) {
3301 chan->buffer_seq = chan->buffer_seq_srej; 3301 chan->buffer_seq = chan->buffer_seq_srej;
3302 chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; 3302 chan->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3303 l2cap_send_ack(chan); 3303 l2cap_send_ack(chan);
@@ -3310,7 +3310,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
3310 if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) 3310 if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0)
3311 goto drop; 3311 goto drop;
3312 3312
3313 list_for_each_entry(l, SREJ_LIST(sk), list) { 3313 list_for_each_entry(l, &chan->srej_l, list) {
3314 if (l->tx_seq == tx_seq) { 3314 if (l->tx_seq == tx_seq) {
3315 l2cap_resend_srejframe(chan, tx_seq); 3315 l2cap_resend_srejframe(chan, tx_seq);
3316 return 0; 3316 return 0;
@@ -3332,7 +3332,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
3332 3332
3333 BT_DBG("sk %p, Enter SREJ", sk); 3333 BT_DBG("sk %p, Enter SREJ", sk);
3334 3334
3335 INIT_LIST_HEAD(SREJ_LIST(sk)); 3335 INIT_LIST_HEAD(&chan->srej_l);
3336 chan->buffer_seq_srej = chan->buffer_seq; 3336 chan->buffer_seq_srej = chan->buffer_seq;
3337 3337
3338 __skb_queue_head_init(&chan->srej_q); 3338 __skb_queue_head_init(&chan->srej_q);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 55dee999af94..16a223bfa8f5 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1018,7 +1018,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
1018 /* Default config options */ 1018 /* Default config options */
1019 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; 1019 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
1020 skb_queue_head_init(TX_QUEUE(sk)); 1020 skb_queue_head_init(TX_QUEUE(sk));
1021 INIT_LIST_HEAD(SREJ_LIST(sk));
1022} 1021}
1023 1022
1024static struct proto l2cap_proto = { 1023static struct proto l2cap_proto = {