aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ifb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ifb.c')
-rw-r--r--drivers/net/ifb.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 819945e3b330..669ee1a1b284 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -139,13 +139,14 @@ resched:
139 139
140} 140}
141 141
142static void __init ifb_setup(struct net_device *dev) 142static void ifb_setup(struct net_device *dev)
143{ 143{
144 /* Initialize the device structure. */ 144 /* Initialize the device structure. */
145 dev->get_stats = ifb_get_stats; 145 dev->get_stats = ifb_get_stats;
146 dev->hard_start_xmit = ifb_xmit; 146 dev->hard_start_xmit = ifb_xmit;
147 dev->open = &ifb_open; 147 dev->open = &ifb_open;
148 dev->stop = &ifb_close; 148 dev->stop = &ifb_close;
149 dev->destructor = free_netdev;
149 150
150 /* Fill in device structure with ethernet-generic values. */ 151 /* Fill in device structure with ethernet-generic values. */
151 ether_setup(dev); 152 ether_setup(dev);
@@ -229,6 +230,37 @@ static int ifb_open(struct net_device *dev)
229 return 0; 230 return 0;
230} 231}
231 232
233static int ifb_newlink(struct net_device *dev,
234 struct nlattr *tb[], struct nlattr *data[])
235{
236 struct ifb_private *priv = netdev_priv(dev);
237 int err;
238
239 err = register_netdevice(dev);
240 if (err < 0)
241 return err;
242
243 priv->dev = dev;
244 list_add_tail(&priv->list, &ifbs);
245 return 0;
246}
247
248static void ifb_dellink(struct net_device *dev)
249{
250 struct ifb_private *priv = netdev_priv(dev);
251
252 list_del(&priv->list);
253 unregister_netdevice(dev);
254}
255
256static struct rtnl_link_ops ifb_link_ops __read_mostly = {
257 .kind = "ifb",
258 .priv_size = sizeof(struct ifb_private),
259 .setup = ifb_setup,
260 .newlink = ifb_newlink,
261 .dellink = ifb_dellink,
262};
263
232static int __init ifb_init_one(int index) 264static int __init ifb_init_one(int index)
233{ 265{
234 struct net_device *dev_ifb; 266 struct net_device *dev_ifb;
@@ -241,38 +273,41 @@ static int __init ifb_init_one(int index)
241 if (!dev_ifb) 273 if (!dev_ifb)
242 return -ENOMEM; 274 return -ENOMEM;
243 275
244 if ((err = register_netdev(dev_ifb))) { 276 err = dev_alloc_name(dev_ifb, dev_ifb->name);
245 free_netdev(dev_ifb); 277 if (err < 0)
246 dev_ifb = NULL; 278 goto err;
247 } else {
248 priv = netdev_priv(dev_ifb);
249 priv->dev = dev_ifb;
250 list_add_tail(&priv->list, &ifbs);
251 }
252 279
253 return err; 280 dev_ifb->rtnl_link_ops = &ifb_link_ops;
254} 281 err = register_netdevice(dev_ifb);
282 if (err < 0)
283 goto err;
255 284
256static void ifb_free_one(struct net_device *dev) 285 priv = netdev_priv(dev_ifb);
257{ 286 priv->dev = dev_ifb;
258 struct ifb_private *priv = netdev_priv(dev); 287 list_add_tail(&priv->list, &ifbs);
288 return 0;
259 289
260 list_del(&priv->list); 290err:
261 unregister_netdev(dev); 291 free_netdev(dev_ifb);
262 free_netdev(dev); 292 return err;
263} 293}
264 294
265static int __init ifb_init_module(void) 295static int __init ifb_init_module(void)
266{ 296{
267 struct ifb_private *priv, *next; 297 struct ifb_private *priv, *next;
268 int i, err = 0; 298 int i, err;
299
300 rtnl_lock();
301 err = __rtnl_link_register(&ifb_link_ops);
269 302
270 for (i = 0; i < numifbs && !err; i++) 303 for (i = 0; i < numifbs && !err; i++)
271 err = ifb_init_one(i); 304 err = ifb_init_one(i);
272 if (err) { 305 if (err) {
273 list_for_each_entry_safe(priv, next, &ifbs, list) 306 list_for_each_entry_safe(priv, next, &ifbs, list)
274 ifb_free_one(priv->dev); 307 ifb_dellink(priv->dev);
308 __rtnl_link_unregister(&ifb_link_ops);
275 } 309 }
310 rtnl_unlock();
276 311
277 return err; 312 return err;
278} 313}
@@ -281,11 +316,16 @@ static void __exit ifb_cleanup_module(void)
281{ 316{
282 struct ifb_private *priv, *next; 317 struct ifb_private *priv, *next;
283 318
319 rtnl_lock();
284 list_for_each_entry_safe(priv, next, &ifbs, list) 320 list_for_each_entry_safe(priv, next, &ifbs, list)
285 ifb_free_one(priv->dev); 321 ifb_dellink(priv->dev);
322
323 __rtnl_link_unregister(&ifb_link_ops);
324 rtnl_unlock();
286} 325}
287 326
288module_init(ifb_init_module); 327module_init(ifb_init_module);
289module_exit(ifb_cleanup_module); 328module_exit(ifb_cleanup_module);
290MODULE_LICENSE("GPL"); 329MODULE_LICENSE("GPL");
291MODULE_AUTHOR("Jamal Hadi Salim"); 330MODULE_AUTHOR("Jamal Hadi Salim");
331MODULE_ALIAS_RTNL_LINK("ifb");