aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/dummy.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 91b474c9bba0..2f2cf3c04bc7 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -34,6 +34,12 @@
34#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/moduleparam.h> 36#include <linux/moduleparam.h>
37#include <linux/rtnetlink.h>
38
39struct dummy_priv {
40 struct net_device *dev;
41 struct list_head list;
42};
37 43
38static int numdummies = 1; 44static int numdummies = 1;
39 45
@@ -81,18 +87,20 @@ static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
81 return 0; 87 return 0;
82} 88}
83 89
84static struct net_device **dummies; 90static LIST_HEAD(dummies);
85 91
86/* Number of dummy devices to be set up by this module. */ 92/* Number of dummy devices to be set up by this module. */
87module_param(numdummies, int, 0); 93module_param(numdummies, int, 0);
88MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices"); 94MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
89 95
90static int __init dummy_init_one(int index) 96static int __init dummy_init_one(void)
91{ 97{
92 struct net_device *dev_dummy; 98 struct net_device *dev_dummy;
99 struct dummy_priv *priv;
93 int err; 100 int err;
94 101
95 dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup); 102 dev_dummy = alloc_netdev(sizeof(struct dummy_priv), "dummy%d",
103 dummy_setup);
96 104
97 if (!dev_dummy) 105 if (!dev_dummy)
98 return -ENOMEM; 106 return -ENOMEM;
@@ -101,40 +109,43 @@ static int __init dummy_init_one(int index)
101 free_netdev(dev_dummy); 109 free_netdev(dev_dummy);
102 dev_dummy = NULL; 110 dev_dummy = NULL;
103 } else { 111 } else {
104 dummies[index] = dev_dummy; 112 priv = netdev_priv(dev_dummy);
113 priv->dev = dev_dummy;
114 list_add_tail(&priv->list, &dummies);
105 } 115 }
106 116
107 return err; 117 return err;
108} 118}
109 119
110static void dummy_free_one(int index) 120static void dummy_free_one(struct net_device *dev)
111{ 121{
112 unregister_netdev(dummies[index]); 122 struct dummy_priv *priv = netdev_priv(dev);
113 free_netdev(dummies[index]); 123
124 list_del(&priv->list);
125 unregister_netdev(dev);
126 free_netdev(dev);
114} 127}
115 128
116static int __init dummy_init_module(void) 129static int __init dummy_init_module(void)
117{ 130{
131 struct dummy_priv *priv, *next;
118 int i, err = 0; 132 int i, err = 0;
119 dummies = kmalloc(numdummies * sizeof(void *), GFP_KERNEL); 133
120 if (!dummies)
121 return -ENOMEM;
122 for (i = 0; i < numdummies && !err; i++) 134 for (i = 0; i < numdummies && !err; i++)
123 err = dummy_init_one(i); 135 err = dummy_init_one();
124 if (err) { 136 if (err) {
125 i--; 137 list_for_each_entry_safe(priv, next, &dummies, list)
126 while (--i >= 0) 138 dummy_free_one(priv->dev);
127 dummy_free_one(i);
128 } 139 }
129 return err; 140 return err;
130} 141}
131 142
132static void __exit dummy_cleanup_module(void) 143static void __exit dummy_cleanup_module(void)
133{ 144{
134 int i; 145 struct dummy_priv *priv, *next;
135 for (i = 0; i < numdummies; i++) 146
136 dummy_free_one(i); 147 list_for_each_entry_safe(priv, next, &dummies, list)
137 kfree(dummies); 148 dummy_free_one(priv->dev);
138} 149}
139 150
140module_init(dummy_init_module); 151module_init(dummy_init_module);