aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/br2684.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/br2684.c')
-rw-r--r--net/atm/br2684.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index b04162f10d85..83a1c1b1d6cd 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -23,7 +23,6 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
23#include <linux/atmbr2684.h> 23#include <linux/atmbr2684.h>
24 24
25#include "common.h" 25#include "common.h"
26#include "ipcommon.h"
27 26
28/* 27/*
29 * Define this to use a version of the code which interacts with the higher 28 * Define this to use a version of the code which interacts with the higher
@@ -500,11 +499,12 @@ Note: we do not have explicit unassign, but look at _push()
500*/ 499*/
501 int err; 500 int err;
502 struct br2684_vcc *brvcc; 501 struct br2684_vcc *brvcc;
503 struct sk_buff_head copy;
504 struct sk_buff *skb; 502 struct sk_buff *skb;
503 struct sk_buff_head *rq;
505 struct br2684_dev *brdev; 504 struct br2684_dev *brdev;
506 struct net_device *net_dev; 505 struct net_device *net_dev;
507 struct atm_backend_br2684 be; 506 struct atm_backend_br2684 be;
507 unsigned long flags;
508 508
509 if (copy_from_user(&be, arg, sizeof be)) 509 if (copy_from_user(&be, arg, sizeof be))
510 return -EFAULT; 510 return -EFAULT;
@@ -554,12 +554,30 @@ Note: we do not have explicit unassign, but look at _push()
554 brvcc->old_push = atmvcc->push; 554 brvcc->old_push = atmvcc->push;
555 barrier(); 555 barrier();
556 atmvcc->push = br2684_push; 556 atmvcc->push = br2684_push;
557 skb_queue_head_init(&copy); 557
558 skb_migrate(&sk_atm(atmvcc)->sk_receive_queue, &copy); 558 rq = &sk_atm(atmvcc)->sk_receive_queue;
559 while ((skb = skb_dequeue(&copy)) != NULL) { 559
560 spin_lock_irqsave(&rq->lock, flags);
561 if (skb_queue_empty(rq)) {
562 skb = NULL;
563 } else {
564 /* NULL terminate the list. */
565 rq->prev->next = NULL;
566 skb = rq->next;
567 }
568 rq->prev = rq->next = (struct sk_buff *)rq;
569 rq->qlen = 0;
570 spin_unlock_irqrestore(&rq->lock, flags);
571
572 while (skb) {
573 struct sk_buff *next = skb->next;
574
575 skb->next = skb->prev = NULL;
560 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; 576 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len;
561 BRPRIV(skb->dev)->stats.rx_packets--; 577 BRPRIV(skb->dev)->stats.rx_packets--;
562 br2684_push(atmvcc, skb); 578 br2684_push(atmvcc, skb);
579
580 skb = next;
563 } 581 }
564 __module_get(THIS_MODULE); 582 __module_get(THIS_MODULE);
565 return 0; 583 return 0;