diff options
| author | Stephen Hemminger <shemminger@osdl.org> | 2003-08-07 06:28:33 +1000 |
|---|---|---|
| committer | Stephen Hemminger <shemminger@osdl.org> | 2003-08-07 06:28:33 +1000 |
| commit | 6ae0b08d7fb678751ec27a2b22f38c771e9eed8f (patch) | |
| tree | 4d749d78ac128d6f1ca14543a9c2c4b9a90c0600 | |
| parent | cd5221688ad84366dfcb9dd7286ecd4766f9d6e6 (diff) | |
[NET] Dynamically allocate net_device structures for ROSE
This patch changes the ROSE protocol to allocate an array of pointers and each network device
separately. This sets up later change where network_device object's are released on last use
which may be after the module is unloaded.
The patch is against 2.6.0-test2 (though this code hasn't changed in a long time).
Allocation is done via alloc_netdev so the dev->priv area is already reserved and
doesn't need to be allocated separately.
| -rw-r--r-- | include/net/rose.h | 2 | ||||
| -rw-r--r-- | net/rose/af_rose.c | 47 | ||||
| -rw-r--r-- | net/rose/rose_dev.c | 12 |
3 files changed, 38 insertions, 23 deletions
diff --git a/include/net/rose.h b/include/net/rose.h index 96d561e15a26..37e8176ee7d2 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -163,7 +163,7 @@ extern void rose_destroy_socket(struct sock *); /* rose_dev.c */ extern int rose_rx_ip(struct sk_buff *, struct net_device *); -extern int rose_init(struct net_device *); +extern void rose_setup(struct net_device *); /* rose_in.c */ extern int rose_process_rx_frame(struct sock *, struct sk_buff *); diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 4beee50e18ff..96fc7d9a087d 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -43,7 +43,7 @@ #include <net/ip.h> #include <net/arp.h> -int rose_ndevs = 10; +static int rose_ndevs = 10; int sysctl_rose_restart_request_timeout = ROSE_DEFAULT_T0; int sysctl_rose_call_request_timeout = ROSE_DEFAULT_T1; @@ -56,7 +56,7 @@ int sysctl_rose_link_fail_timeout = ROSE_DEFAULT_FAIL_TIMEOUT; int sysctl_rose_maximum_vcs = ROSE_DEFAULT_MAXVC; int sysctl_rose_window_size = ROSE_DEFAULT_WINDOW_SIZE; -HLIST_HEAD(rose_list); +static HLIST_HEAD(rose_list); static spinlock_t rose_list_lock = SPIN_LOCK_UNLOCKED; static struct proto_ops rose_proto_ops; @@ -1435,7 +1435,7 @@ static struct notifier_block rose_dev_notifier = { .notifier_call = rose_device_event, }; -static struct net_device *dev_rose; +static struct net_device **dev_rose; static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n"; @@ -1450,17 +1450,39 @@ static int __init rose_proto_init(void) return -1; } - if ((dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) { + dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL); + if (dev_rose == NULL) { printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); return -1; } - memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device)); + memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*)); + for (i = 0; i < rose_ndevs; i++) { + struct net_device *dev; + char name[IFNAMSIZ]; + + sprintf(name, "rose%d", i); + dev = alloc_netdev(sizeof(struct net_device_stats), + name, rose_setup); + if (!dev) { + printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n"); + while (--i >= 0) + kfree(dev_rose[i]); + return -ENOMEM; + } + dev_rose[i] = dev; + } for (i = 0; i < rose_ndevs; i++) { - sprintf(dev_rose[i].name, "rose%d", i); - dev_rose[i].init = rose_init; - register_netdev(&dev_rose[i]); + if (register_netdev(dev_rose[i])) { + printk(KERN_ERR "ROSE: netdevice regeistration failed\n"); + while (--i >= 0) { + unregister_netdev(dev_rose[i]); + kfree(dev_rose[i]); + return -EIO; + } + } + } sock_register(&rose_family_ops); @@ -1518,10 +1540,11 @@ static void __exit rose_exit(void) sock_unregister(PF_ROSE); for (i = 0; i < rose_ndevs; i++) { - if (dev_rose[i].priv != NULL) { - kfree(dev_rose[i].priv); - dev_rose[i].priv = NULL; - unregister_netdev(&dev_rose[i]); + struct net_device *dev = dev_rose[i]; + + if (dev) { + unregister_netdev(dev); + kfree(dev); } } diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index 45adce6ea28e..d779e071b97d 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c @@ -165,7 +165,7 @@ static struct net_device_stats *rose_get_stats(struct net_device *dev) return (struct net_device_stats *)dev->priv; } -int rose_init(struct net_device *dev) +void rose_setup(struct net_device *dev) { SET_MODULE_OWNER(dev); dev->mtu = ROSE_MAX_PACKET_SIZE - 2; @@ -182,13 +182,5 @@ int rose_init(struct net_device *dev) /* New-style flags. */ dev->flags = 0; - - if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL) - return -ENOMEM; - - memset(dev->priv, 0, sizeof(struct net_device_stats)); - dev->get_stats = rose_get_stats; - - return 0; -}; +} |
