aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMat Martineau <mathewm@codeaurora.org>2011-07-07 12:39:01 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-07-07 14:28:51 -0400
commit26f880d221302b5d061185d8a6795bb532693bf3 (patch)
treed273295304e084da43f2a3bb04036d63b2f96c13 /net
parent8c156c322f8a300afe59259bd554db166cf88203 (diff)
Bluetooth: Move code for ERTM local busy state to separate functions
The local busy state is entered and exited based on buffer status in the socket layer (or other upper layer). This change is in preparation for general buffer status reports from the socket layer, which will then be used to change the local busy status. Signed-off-by: Mat Martineau <mathewm@codeaurora.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index bd5d9926bf4f..f7ada4a2cc5d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3227,22 +3227,26 @@ disconnect:
3227 return 0; 3227 return 0;
3228} 3228}
3229 3229
3230static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) 3230static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
3231{ 3231{
3232 struct sk_buff *skb;
3233 u16 control; 3232 u16 control;
3234 int err;
3235 3233
3236 while ((skb = skb_dequeue(&chan->busy_q))) { 3234 BT_DBG("chan %p, Enter local busy", chan);
3237 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3238 err = l2cap_ertm_reassembly_sdu(chan, skb, control);
3239 if (err < 0) {
3240 skb_queue_head(&chan->busy_q, skb);
3241 return -EBUSY;
3242 }
3243 3235
3244 chan->buffer_seq = (chan->buffer_seq + 1) % 64; 3236 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
3245 } 3237
3238 control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3239 control |= L2CAP_SUPER_RCV_NOT_READY;
3240 l2cap_send_sframe(chan, control);
3241
3242 set_bit(CONN_RNR_SENT, &chan->conn_state);
3243
3244 __clear_ack_timer(chan);
3245}
3246
3247static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan)
3248{
3249 u16 control;
3246 3250
3247 if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) 3251 if (!test_bit(CONN_RNR_SENT, &chan->conn_state))
3248 goto done; 3252 goto done;
@@ -3262,6 +3266,26 @@ done:
3262 clear_bit(CONN_RNR_SENT, &chan->conn_state); 3266 clear_bit(CONN_RNR_SENT, &chan->conn_state);
3263 3267
3264 BT_DBG("chan %p, Exit local busy", chan); 3268 BT_DBG("chan %p, Exit local busy", chan);
3269}
3270
3271static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
3272{
3273 struct sk_buff *skb;
3274 u16 control;
3275 int err;
3276
3277 while ((skb = skb_dequeue(&chan->busy_q))) {
3278 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3279 err = l2cap_ertm_reassembly_sdu(chan, skb, control);
3280 if (err < 0) {
3281 skb_queue_head(&chan->busy_q, skb);
3282 return -EBUSY;
3283 }
3284
3285 chan->buffer_seq = (chan->buffer_seq + 1) % 64;
3286 }
3287
3288 l2cap_ertm_exit_local_busy(chan);
3265 3289
3266 return 0; 3290 return 0;
3267} 3291}
@@ -3315,7 +3339,7 @@ static void l2cap_busy_work(struct work_struct *work)
3315 3339
3316static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) 3340static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
3317{ 3341{
3318 int sctrl, err; 3342 int err;
3319 3343
3320 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { 3344 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
3321 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; 3345 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
@@ -3331,21 +3355,11 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
3331 return err; 3355 return err;
3332 } 3356 }
3333 3357
3334 /* Busy Condition */ 3358 l2cap_ertm_enter_local_busy(chan);
3335 BT_DBG("chan %p, Enter local busy", chan);
3336 3359
3337 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
3338 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; 3360 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3339 __skb_queue_tail(&chan->busy_q, skb); 3361 __skb_queue_tail(&chan->busy_q, skb);
3340 3362
3341 sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3342 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3343 l2cap_send_sframe(chan, sctrl);
3344
3345 set_bit(CONN_RNR_SENT, &chan->conn_state);
3346
3347 __clear_ack_timer(chan);
3348
3349 queue_work(_busy_wq, &chan->busy_work); 3363 queue_work(_busy_wq, &chan->busy_work);
3350 3364
3351 return err; 3365 return err;