summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/mISDN/hfcmulti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcmulti.c')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 0928fd1f0..60b3a4aab 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3233,6 +3233,7 @@ static int
hfcm_l1callback(struct dchannel *dch, u_int cmd)
{
struct hfc_multi *hc = dch->hw;
+ struct sk_buff_head free_queue;
u_long flags;
switch (cmd) {
@@ -3261,6 +3262,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
l1_event(dch->l1, HW_POWERUP_IND);
break;
case HW_DEACT_REQ:
+ __skb_queue_head_init(&free_queue);
/* start deactivation */
spin_lock_irqsave(&hc->lock, flags);
if (hc->ctype == HFC_TYPE_E1) {
@@ -3280,20 +3282,21 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
plxsd_checksync(hc, 0);
}
}
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
spin_unlock_irqrestore(&hc->lock, flags);
+ __skb_queue_purge(&free_queue);
break;
case HW_POWERUP_REQ:
spin_lock_irqsave(&hc->lock, flags);
@@ -3400,6 +3403,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
case PH_DEACTIVATE_REQ:
test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
if (dch->dev.D.protocol != ISDN_P_TE_S0) {
+ struct sk_buff_head free_queue;
+
+ __skb_queue_head_init(&free_queue);
spin_lock_irqsave(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
@@ -3421,14 +3427,14 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
/* deactivate */
dch->state = 1;
}
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
@@ -3440,6 +3446,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
#endif
ret = 0;
spin_unlock_irqrestore(&hc->lock, flags);
+ __skb_queue_purge(&free_queue);
} else
ret = l1_event(dch->l1, hh->prim);
break;