diff options
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r-- | drivers/net/ppp_generic.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c832d600d1e8..06b448285eb5 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -117,6 +117,7 @@ struct ppp { | |||
117 | unsigned long last_xmit; /* jiffies when last pkt sent 9c */ | 117 | unsigned long last_xmit; /* jiffies when last pkt sent 9c */ |
118 | unsigned long last_recv; /* jiffies when last pkt rcvd a0 */ | 118 | unsigned long last_recv; /* jiffies when last pkt rcvd a0 */ |
119 | struct net_device *dev; /* network interface device a4 */ | 119 | struct net_device *dev; /* network interface device a4 */ |
120 | int closing; /* is device closing down? a8 */ | ||
120 | #ifdef CONFIG_PPP_MULTILINK | 121 | #ifdef CONFIG_PPP_MULTILINK |
121 | int nxchan; /* next channel to send something on */ | 122 | int nxchan; /* next channel to send something on */ |
122 | u32 nxseq; /* next sequence number to send */ | 123 | u32 nxseq; /* next sequence number to send */ |
@@ -983,7 +984,7 @@ ppp_xmit_process(struct ppp *ppp) | |||
983 | struct sk_buff *skb; | 984 | struct sk_buff *skb; |
984 | 985 | ||
985 | ppp_xmit_lock(ppp); | 986 | ppp_xmit_lock(ppp); |
986 | if (ppp->dev) { | 987 | if (!ppp->closing) { |
987 | ppp_push(ppp); | 988 | ppp_push(ppp); |
988 | while (!ppp->xmit_pending | 989 | while (!ppp->xmit_pending |
989 | && (skb = skb_dequeue(&ppp->file.xq))) | 990 | && (skb = skb_dequeue(&ppp->file.xq))) |
@@ -1451,8 +1452,7 @@ static inline void | |||
1451 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | 1452 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) |
1452 | { | 1453 | { |
1453 | ppp_recv_lock(ppp); | 1454 | ppp_recv_lock(ppp); |
1454 | /* ppp->dev == 0 means interface is closing down */ | 1455 | if (!ppp->closing) |
1455 | if (ppp->dev) | ||
1456 | ppp_receive_frame(ppp, skb, pch); | 1456 | ppp_receive_frame(ppp, skb, pch); |
1457 | else | 1457 | else |
1458 | kfree_skb(skb); | 1458 | kfree_skb(skb); |
@@ -2484,18 +2484,16 @@ init_ppp_file(struct ppp_file *pf, int kind) | |||
2484 | */ | 2484 | */ |
2485 | static void ppp_shutdown_interface(struct ppp *ppp) | 2485 | static void ppp_shutdown_interface(struct ppp *ppp) |
2486 | { | 2486 | { |
2487 | struct net_device *dev; | ||
2488 | |||
2489 | mutex_lock(&all_ppp_mutex); | 2487 | mutex_lock(&all_ppp_mutex); |
2490 | ppp_lock(ppp); | ||
2491 | dev = ppp->dev; | ||
2492 | ppp->dev = NULL; | ||
2493 | ppp_unlock(ppp); | ||
2494 | /* This will call dev_close() for us. */ | 2488 | /* This will call dev_close() for us. */ |
2495 | if (dev) { | 2489 | ppp_lock(ppp); |
2496 | unregister_netdev(dev); | 2490 | if (!ppp->closing) { |
2497 | free_netdev(dev); | 2491 | ppp->closing = 1; |
2498 | } | 2492 | ppp_unlock(ppp); |
2493 | unregister_netdev(ppp->dev); | ||
2494 | } else | ||
2495 | ppp_unlock(ppp); | ||
2496 | |||
2499 | unit_put(&ppp_units_idr, ppp->file.index); | 2497 | unit_put(&ppp_units_idr, ppp->file.index); |
2500 | ppp->file.dead = 1; | 2498 | ppp->file.dead = 1; |
2501 | ppp->owner = NULL; | 2499 | ppp->owner = NULL; |
@@ -2540,7 +2538,7 @@ static void ppp_destroy_interface(struct ppp *ppp) | |||
2540 | if (ppp->xmit_pending) | 2538 | if (ppp->xmit_pending) |
2541 | kfree_skb(ppp->xmit_pending); | 2539 | kfree_skb(ppp->xmit_pending); |
2542 | 2540 | ||
2543 | kfree(ppp); | 2541 | free_netdev(ppp->dev); |
2544 | } | 2542 | } |
2545 | 2543 | ||
2546 | /* | 2544 | /* |
@@ -2602,7 +2600,7 @@ ppp_connect_channel(struct channel *pch, int unit) | |||
2602 | if (pch->file.hdrlen > ppp->file.hdrlen) | 2600 | if (pch->file.hdrlen > ppp->file.hdrlen) |
2603 | ppp->file.hdrlen = pch->file.hdrlen; | 2601 | ppp->file.hdrlen = pch->file.hdrlen; |
2604 | hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */ | 2602 | hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */ |
2605 | if (ppp->dev && hdrlen > ppp->dev->hard_header_len) | 2603 | if (hdrlen > ppp->dev->hard_header_len) |
2606 | ppp->dev->hard_header_len = hdrlen; | 2604 | ppp->dev->hard_header_len = hdrlen; |
2607 | list_add_tail(&pch->clist, &ppp->channels); | 2605 | list_add_tail(&pch->clist, &ppp->channels); |
2608 | ++ppp->n_channels; | 2606 | ++ppp->n_channels; |