.. | .. |
---|
3219 | 3219 | hfcm_l1callback(struct dchannel *dch, u_int cmd) |
---|
3220 | 3220 | { |
---|
3221 | 3221 | struct hfc_multi *hc = dch->hw; |
---|
| 3222 | + struct sk_buff_head free_queue; |
---|
3222 | 3223 | u_long flags; |
---|
3223 | 3224 | |
---|
3224 | 3225 | switch (cmd) { |
---|
.. | .. |
---|
3247 | 3248 | l1_event(dch->l1, HW_POWERUP_IND); |
---|
3248 | 3249 | break; |
---|
3249 | 3250 | case HW_DEACT_REQ: |
---|
| 3251 | + __skb_queue_head_init(&free_queue); |
---|
3250 | 3252 | /* start deactivation */ |
---|
3251 | 3253 | spin_lock_irqsave(&hc->lock, flags); |
---|
3252 | 3254 | if (hc->ctype == HFC_TYPE_E1) { |
---|
.. | .. |
---|
3266 | 3268 | plxsd_checksync(hc, 0); |
---|
3267 | 3269 | } |
---|
3268 | 3270 | } |
---|
3269 | | - skb_queue_purge(&dch->squeue); |
---|
| 3271 | + skb_queue_splice_init(&dch->squeue, &free_queue); |
---|
3270 | 3272 | if (dch->tx_skb) { |
---|
3271 | | - dev_kfree_skb(dch->tx_skb); |
---|
| 3273 | + __skb_queue_tail(&free_queue, dch->tx_skb); |
---|
3272 | 3274 | dch->tx_skb = NULL; |
---|
3273 | 3275 | } |
---|
3274 | 3276 | dch->tx_idx = 0; |
---|
3275 | 3277 | if (dch->rx_skb) { |
---|
3276 | | - dev_kfree_skb(dch->rx_skb); |
---|
| 3278 | + __skb_queue_tail(&free_queue, dch->rx_skb); |
---|
3277 | 3279 | dch->rx_skb = NULL; |
---|
3278 | 3280 | } |
---|
3279 | 3281 | test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); |
---|
3280 | 3282 | if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) |
---|
3281 | 3283 | del_timer(&dch->timer); |
---|
3282 | 3284 | spin_unlock_irqrestore(&hc->lock, flags); |
---|
| 3285 | + __skb_queue_purge(&free_queue); |
---|
3283 | 3286 | break; |
---|
3284 | 3287 | case HW_POWERUP_REQ: |
---|
3285 | 3288 | spin_lock_irqsave(&hc->lock, flags); |
---|
.. | .. |
---|
3386 | 3389 | case PH_DEACTIVATE_REQ: |
---|
3387 | 3390 | test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); |
---|
3388 | 3391 | if (dch->dev.D.protocol != ISDN_P_TE_S0) { |
---|
| 3392 | + struct sk_buff_head free_queue; |
---|
| 3393 | + |
---|
| 3394 | + __skb_queue_head_init(&free_queue); |
---|
3389 | 3395 | spin_lock_irqsave(&hc->lock, flags); |
---|
3390 | 3396 | if (debug & DEBUG_HFCMULTI_MSG) |
---|
3391 | 3397 | printk(KERN_DEBUG |
---|
.. | .. |
---|
3407 | 3413 | /* deactivate */ |
---|
3408 | 3414 | dch->state = 1; |
---|
3409 | 3415 | } |
---|
3410 | | - skb_queue_purge(&dch->squeue); |
---|
| 3416 | + skb_queue_splice_init(&dch->squeue, &free_queue); |
---|
3411 | 3417 | if (dch->tx_skb) { |
---|
3412 | | - dev_kfree_skb(dch->tx_skb); |
---|
| 3418 | + __skb_queue_tail(&free_queue, dch->tx_skb); |
---|
3413 | 3419 | dch->tx_skb = NULL; |
---|
3414 | 3420 | } |
---|
3415 | 3421 | dch->tx_idx = 0; |
---|
3416 | 3422 | if (dch->rx_skb) { |
---|
3417 | | - dev_kfree_skb(dch->rx_skb); |
---|
| 3423 | + __skb_queue_tail(&free_queue, dch->rx_skb); |
---|
3418 | 3424 | dch->rx_skb = NULL; |
---|
3419 | 3425 | } |
---|
3420 | 3426 | test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); |
---|
.. | .. |
---|
3426 | 3432 | #endif |
---|
3427 | 3433 | ret = 0; |
---|
3428 | 3434 | spin_unlock_irqrestore(&hc->lock, flags); |
---|
| 3435 | + __skb_queue_purge(&free_queue); |
---|
3429 | 3436 | } else |
---|
3430 | 3437 | ret = l1_event(dch->l1, hh->prim); |
---|
3431 | 3438 | break; |
---|