aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ifb.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-11 22:42:13 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 22:45:33 -0400
commit2d85cba2b272a5201a60966a65a4f8c0bcc0bb71 (patch)
treef8dd1ca6d7c963eade714a4ecc7aec4d7751f55a /drivers/net/ifb.c
parent8c979c26a0f093c13290320edda799d8335e50ae (diff)
[RTNETLINK]: rtnl_link API simplification
All drivers need to unregister their devices in the module unload function. While doing so they must hold the rtnl and atomically unregister the rtnl_link ops as well. This makes the rtnl_link_unregister function that takes the rtnl itself completely useless. Provide default newlink/dellink functions, make __rtnl_link_unregister and rtnl_link_unregister unregister all devices with matching rtnl_link_ops and change the existing users to take advantage of that. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ifb.c')
-rw-r--r--drivers/net/ifb.c58
1 files changed, 6 insertions, 52 deletions
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 669ee1a1b284..c8e7c8f6ba3e 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -33,15 +33,12 @@
33#include <linux/etherdevice.h> 33#include <linux/etherdevice.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/list.h>
37#include <net/pkt_sched.h> 36#include <net/pkt_sched.h>
38 37
39#define TX_TIMEOUT (2*HZ) 38#define TX_TIMEOUT (2*HZ)
40 39
41#define TX_Q_LIMIT 32 40#define TX_Q_LIMIT 32
42struct ifb_private { 41struct ifb_private {
43 struct list_head list;
44 struct net_device *dev;
45 struct net_device_stats stats; 42 struct net_device_stats stats;
46 struct tasklet_struct ifb_tasklet; 43 struct tasklet_struct ifb_tasklet;
47 int tasklet_pending; 44 int tasklet_pending;
@@ -201,12 +198,6 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev)
201 return stats; 198 return stats;
202} 199}
203 200
204static LIST_HEAD(ifbs);
205
206/* Number of ifb devices to be set up by this module. */
207module_param(numifbs, int, 0);
208MODULE_PARM_DESC(numifbs, "Number of ifb devices");
209
210static int ifb_close(struct net_device *dev) 201static int ifb_close(struct net_device *dev)
211{ 202{
212 struct ifb_private *dp = netdev_priv(dev); 203 struct ifb_private *dp = netdev_priv(dev);
@@ -230,41 +221,19 @@ static int ifb_open(struct net_device *dev)
230 return 0; 221 return 0;
231} 222}
232 223
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 = { 224static struct rtnl_link_ops ifb_link_ops __read_mostly = {
257 .kind = "ifb", 225 .kind = "ifb",
258 .priv_size = sizeof(struct ifb_private), 226 .priv_size = sizeof(struct ifb_private),
259 .setup = ifb_setup, 227 .setup = ifb_setup,
260 .newlink = ifb_newlink,
261 .dellink = ifb_dellink,
262}; 228};
263 229
230/* Number of ifb devices to be set up by this module. */
231module_param(numifbs, int, 0);
232MODULE_PARM_DESC(numifbs, "Number of ifb devices");
233
264static int __init ifb_init_one(int index) 234static int __init ifb_init_one(int index)
265{ 235{
266 struct net_device *dev_ifb; 236 struct net_device *dev_ifb;
267 struct ifb_private *priv;
268 int err; 237 int err;
269 238
270 dev_ifb = alloc_netdev(sizeof(struct ifb_private), 239 dev_ifb = alloc_netdev(sizeof(struct ifb_private),
@@ -281,10 +250,6 @@ static int __init ifb_init_one(int index)
281 err = register_netdevice(dev_ifb); 250 err = register_netdevice(dev_ifb);
282 if (err < 0) 251 if (err < 0)
283 goto err; 252 goto err;
284
285 priv = netdev_priv(dev_ifb);
286 priv->dev = dev_ifb;
287 list_add_tail(&priv->list, &ifbs);
288 return 0; 253 return 0;
289 254
290err: 255err:
@@ -294,7 +259,6 @@ err:
294 259
295static int __init ifb_init_module(void) 260static int __init ifb_init_module(void)
296{ 261{
297 struct ifb_private *priv, *next;
298 int i, err; 262 int i, err;
299 263
300 rtnl_lock(); 264 rtnl_lock();
@@ -302,11 +266,8 @@ static int __init ifb_init_module(void)
302 266
303 for (i = 0; i < numifbs && !err; i++) 267 for (i = 0; i < numifbs && !err; i++)
304 err = ifb_init_one(i); 268 err = ifb_init_one(i);
305 if (err) { 269 if (err)
306 list_for_each_entry_safe(priv, next, &ifbs, list)
307 ifb_dellink(priv->dev);
308 __rtnl_link_unregister(&ifb_link_ops); 270 __rtnl_link_unregister(&ifb_link_ops);
309 }
310 rtnl_unlock(); 271 rtnl_unlock();
311 272
312 return err; 273 return err;
@@ -314,14 +275,7 @@ static int __init ifb_init_module(void)
314 275
315static void __exit ifb_cleanup_module(void) 276static void __exit ifb_cleanup_module(void)
316{ 277{
317 struct ifb_private *priv, *next; 278 rtnl_link_unregister(&ifb_link_ops);
318
319 rtnl_lock();
320 list_for_each_entry_safe(priv, next, &ifbs, list)
321 ifb_dellink(priv->dev);
322
323 __rtnl_link_unregister(&ifb_link_ops);
324 rtnl_unlock();
325} 279}
326 280
327module_init(ifb_init_module); 281module_init(ifb_init_module);