| .. | .. |
|---|
| 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; |
|---|