Commit 41e883f3 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

[NETROM]: Convert to alloc_netdev().

Convert net_device's from array of structures to an array
of pointers, so they can be freed individually on module
exit.  The net_device_stats are stored at dev->priv.
parent 1ec888ed
...@@ -183,7 +183,7 @@ extern void nr_destroy_socket(struct sock *); ...@@ -183,7 +183,7 @@ extern void nr_destroy_socket(struct sock *);
/* nr_dev.c */ /* nr_dev.c */
extern int nr_rx_ip(struct sk_buff *, struct net_device *); extern int nr_rx_ip(struct sk_buff *, struct net_device *);
extern int nr_init(struct net_device *); extern void nr_setup(struct net_device *);
/* nr_in.c */ /* nr_in.c */
extern int nr_process_rx_frame(struct sock *, struct sk_buff *); extern int nr_process_rx_frame(struct sock *, struct sk_buff *);
......
...@@ -1341,7 +1341,7 @@ static struct notifier_block nr_dev_notifier = { ...@@ -1341,7 +1341,7 @@ static struct notifier_block nr_dev_notifier = {
.notifier_call = nr_device_event, .notifier_call = nr_device_event,
}; };
static struct net_device *dev_nr; static struct net_device **dev_nr;
static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n"; static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
...@@ -1354,21 +1354,39 @@ static int __init nr_proto_init(void) ...@@ -1354,21 +1354,39 @@ static int __init nr_proto_init(void)
return -1; return -1;
} }
if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) { dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL);
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); if (dev_nr == NULL) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n");
return -1; return -1;
} }
memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device)); memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device *));
for (i = 0; i < nr_ndevs; i++) { for (i = 0; i < nr_ndevs; i++) {
sprintf(dev_nr[i].name, "nr%d", i); char name[IFNAMSIZ];
dev_nr[i].base_addr = i; struct net_device *dev;
dev_nr[i].init = nr_init;
register_netdev(&dev_nr[i]); sprintf(name, "nr%d", i);
dev = alloc_netdev(sizeof(struct net_device_stats), name,
nr_setup);
if (!dev) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
goto fail;
}
dev->base_addr = i;
if (register_netdev(dev)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register network device\n");
goto fail;
}
dev_nr[i] = dev;
}
if (sock_register(&nr_family_ops)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register socket family\n");
goto fail;
} }
sock_register(&nr_family_ops);
register_netdevice_notifier(&nr_dev_notifier); register_netdevice_notifier(&nr_dev_notifier);
printk(banner); printk(banner);
...@@ -1385,6 +1403,11 @@ static int __init nr_proto_init(void) ...@@ -1385,6 +1403,11 @@ static int __init nr_proto_init(void)
proc_net_create("nr_neigh", 0, nr_neigh_get_info); proc_net_create("nr_neigh", 0, nr_neigh_get_info);
proc_net_create("nr_nodes", 0, nr_nodes_get_info); proc_net_create("nr_nodes", 0, nr_nodes_get_info);
return 0; return 0;
fail:
while (--i >= 0)
unregister_netdev(dev_nr[i]);
kfree(dev_nr);
return -1;
} }
module_init(nr_proto_init); module_init(nr_proto_init);
...@@ -1420,11 +1443,9 @@ static void __exit nr_exit(void) ...@@ -1420,11 +1443,9 @@ static void __exit nr_exit(void)
sock_unregister(PF_NETROM); sock_unregister(PF_NETROM);
for (i = 0; i < nr_ndevs; i++) { for (i = 0; i < nr_ndevs; i++) {
if (dev_nr[i].priv != NULL) { struct net_device *dev = dev_nr[i];
unregister_netdev(&dev_nr[i]); if (dev)
kfree(dev_nr[i].priv); unregister_netdev(dev);
dev_nr[i].priv = NULL;
}
} }
kfree(dev_nr); kfree(dev_nr);
......
...@@ -197,13 +197,14 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev) ...@@ -197,13 +197,14 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev)
return (struct net_device_stats *)dev->priv; return (struct net_device_stats *)dev->priv;
} }
int nr_init(struct net_device *dev) void nr_setup(struct net_device *dev)
{ {
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
dev->mtu = NR_MAX_PACKET_SIZE; dev->mtu = NR_MAX_PACKET_SIZE;
dev->hard_start_xmit = nr_xmit; dev->hard_start_xmit = nr_xmit;
dev->open = nr_open; dev->open = nr_open;
dev->stop = nr_close; dev->stop = nr_close;
dev->destructor = (void (*)(struct net_device *))kfree;
dev->hard_header = nr_header; dev->hard_header = nr_header;
dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
...@@ -216,12 +217,5 @@ int nr_init(struct net_device *dev) ...@@ -216,12 +217,5 @@ int nr_init(struct net_device *dev)
/* New-style flags. */ /* New-style flags. */
dev->flags = 0; 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 = nr_get_stats; dev->get_stats = nr_get_stats;
}
return 0;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment