aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ppp_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r--drivers/net/ppp_generic.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 3ee7830d458..06b448285eb 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -117,6 +117,7 @@ struct ppp {
unsigned long last_xmit; /* jiffies when last pkt sent 9c */
unsigned long last_recv; /* jiffies when last pkt rcvd a0 */
struct net_device *dev; /* network interface device a4 */
+ int closing; /* is device closing down? a8 */
#ifdef CONFIG_PPP_MULTILINK
int nxchan; /* next channel to send something on */
u32 nxseq; /* next sequence number to send */
@@ -179,7 +180,7 @@ struct channel {
*/
static DEFINE_MUTEX(all_ppp_mutex);
static atomic_t ppp_unit_count = ATOMIC_INIT(0);
-static struct idr ppp_units_idr;
+static DEFINE_IDR(ppp_units_idr);
/*
* all_channels_lock protects all_channels and last_channel_index,
@@ -852,8 +853,6 @@ static int __init ppp_init(void)
"ppp");
}
- idr_init(&ppp_units_idr);
-
out:
if (err)
printk(KERN_ERR "failed to register PPP device (%d)\n", err);
@@ -985,7 +984,7 @@ ppp_xmit_process(struct ppp *ppp)
struct sk_buff *skb;
ppp_xmit_lock(ppp);
- if (ppp->dev) {
+ if (!ppp->closing) {
ppp_push(ppp);
while (!ppp->xmit_pending
&& (skb = skb_dequeue(&ppp->file.xq)))
@@ -1453,8 +1452,7 @@ static inline void
ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{
ppp_recv_lock(ppp);
- /* ppp->dev == 0 means interface is closing down */
- if (ppp->dev)
+ if (!ppp->closing)
ppp_receive_frame(ppp, skb, pch);
else
kfree_skb(skb);
@@ -2435,7 +2433,7 @@ ppp_create_interface(int unit, int *retp)
if (unit_find(&ppp_units_idr, unit))
goto out2; /* unit already exists */
else {
- /* darn, someone is cheatting us? */
+ /* darn, someone is cheating us? */
*retp = -EINVAL;
goto out2;
}
@@ -2486,18 +2484,16 @@ init_ppp_file(struct ppp_file *pf, int kind)
*/
static void ppp_shutdown_interface(struct ppp *ppp)
{
- struct net_device *dev;
-
mutex_lock(&all_ppp_mutex);
- ppp_lock(ppp);
- dev = ppp->dev;
- ppp->dev = NULL;
- ppp_unlock(ppp);
/* This will call dev_close() for us. */
- if (dev) {
- unregister_netdev(dev);
- free_netdev(dev);
- }
+ ppp_lock(ppp);
+ if (!ppp->closing) {
+ ppp->closing = 1;
+ ppp_unlock(ppp);
+ unregister_netdev(ppp->dev);
+ } else
+ ppp_unlock(ppp);
+
unit_put(&ppp_units_idr, ppp->file.index);
ppp->file.dead = 1;
ppp->owner = NULL;
@@ -2542,7 +2538,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
if (ppp->xmit_pending)
kfree_skb(ppp->xmit_pending);
- kfree(ppp);
+ free_netdev(ppp->dev);
}
/*
@@ -2604,7 +2600,7 @@ ppp_connect_channel(struct channel *pch, int unit)
if (pch->file.hdrlen > ppp->file.hdrlen)
ppp->file.hdrlen = pch->file.hdrlen;
hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */
- if (ppp->dev && hdrlen > ppp->dev->hard_header_len)
+ if (hdrlen > ppp->dev->hard_header_len)
ppp->dev->hard_header_len = hdrlen;
list_add_tail(&pch->clist, &ppp->channels);
++ppp->n_channels;