Commit 62b7ffca authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[IFB]: Keep ifb devices on list

Use a list instead of an array to allow creating new devices.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d5cb173
...@@ -33,12 +33,15 @@ ...@@ -33,12 +33,15 @@
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/list.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#define TX_TIMEOUT (2*HZ) #define TX_TIMEOUT (2*HZ)
#define TX_Q_LIMIT 32 #define TX_Q_LIMIT 32
struct ifb_private { struct ifb_private {
struct list_head list;
struct net_device *dev;
struct net_device_stats stats; struct net_device_stats stats;
struct tasklet_struct ifb_tasklet; struct tasklet_struct ifb_tasklet;
int tasklet_pending; int tasklet_pending;
...@@ -197,7 +200,7 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev) ...@@ -197,7 +200,7 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev)
return stats; return stats;
} }
static struct net_device **ifbs; static LIST_HEAD(ifbs);
/* Number of ifb devices to be set up by this module. */ /* Number of ifb devices to be set up by this module. */
module_param(numifbs, int, 0); module_param(numifbs, int, 0);
...@@ -229,6 +232,7 @@ static int ifb_open(struct net_device *dev) ...@@ -229,6 +232,7 @@ static int ifb_open(struct net_device *dev)
static int __init ifb_init_one(int index) static int __init ifb_init_one(int index)
{ {
struct net_device *dev_ifb; struct net_device *dev_ifb;
struct ifb_private *priv;
int err; int err;
dev_ifb = alloc_netdev(sizeof(struct ifb_private), dev_ifb = alloc_netdev(sizeof(struct ifb_private),
...@@ -241,30 +245,33 @@ static int __init ifb_init_one(int index) ...@@ -241,30 +245,33 @@ static int __init ifb_init_one(int index)
free_netdev(dev_ifb); free_netdev(dev_ifb);
dev_ifb = NULL; dev_ifb = NULL;
} else { } else {
ifbs[index] = dev_ifb; priv = netdev_priv(dev_ifb);
priv->dev = dev_ifb;
list_add_tail(&priv->list, &ifbs);
} }
return err; return err;
} }
static void ifb_free_one(int index) static void ifb_free_one(struct net_device *dev)
{ {
unregister_netdev(ifbs[index]); struct ifb_private *priv = netdev_priv(dev);
free_netdev(ifbs[index]);
list_del(&priv->list);
unregister_netdev(dev);
free_netdev(dev);
} }
static int __init ifb_init_module(void) static int __init ifb_init_module(void)
{ {
struct ifb_private *priv, *next;
int i, err = 0; int i, err = 0;
ifbs = kmalloc(numifbs * sizeof(void *), GFP_KERNEL);
if (!ifbs)
return -ENOMEM;
for (i = 0; i < numifbs && !err; i++) for (i = 0; i < numifbs && !err; i++)
err = ifb_init_one(i); err = ifb_init_one(i);
if (err) { if (err) {
i--; list_for_each_entry_safe(priv, next, &ifbs, list)
while (--i >= 0) ifb_free_one(priv->dev);
ifb_free_one(i);
} }
return err; return err;
...@@ -272,11 +279,10 @@ static int __init ifb_init_module(void) ...@@ -272,11 +279,10 @@ static int __init ifb_init_module(void)
static void __exit ifb_cleanup_module(void) static void __exit ifb_cleanup_module(void)
{ {
int i; struct ifb_private *priv, *next;
for (i = 0; i < numifbs; i++) list_for_each_entry_safe(priv, next, &ifbs, list)
ifb_free_one(i); ifb_free_one(priv->dev);
kfree(ifbs);
} }
module_init(ifb_init_module); module_init(ifb_init_module);
......
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