summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2003-09-03 10:41:35 -0700
committerStephen Hemminger <shemminger@osdl.org>2003-09-03 10:41:35 -0700
commit4e39f29be0eae39e05bdb2d881849ff0560a7b64 (patch)
tree6f67dac8316d1c99bfa3e418ff2acaa82cbd8ba3 /drivers
parent4976b816869168610853f5a49cecac852404681b (diff)
[NET]: Loopback device simplification.
Now that all the magic chain of static devices is gone from Space.c The initialization of the one remaining static device (ie the loopback driver) can be simplified. One small change was to reduce possibility of failing the initialization if allocation of private data failed by just going without statistics.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/Space.c29
-rw-r--r--drivers/net/loopback.c72
2 files changed, 50 insertions, 51 deletions
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index a8a92838db26..470cae32a543 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -39,9 +39,6 @@
#include <linux/netlink.h>
#include <linux/divert.h>
-#define NEXT_DEV NULL
-
-
/* A unified ethernet device probe. This is the easiest way to have every
ethernet adaptor have the name "eth[0123...]".
*/
@@ -438,11 +435,23 @@ static __init int trif_probe(void)
}
#endif
+
+/*
+ * The loopback device is global so it can be directly referenced
+ * by the network code. Also, it must be first on device list.
+ */
+extern int loopback_init(void);
+
/* Statically configured drivers -- order matters here. */
void __init probe_old_netdevs(void)
{
int num;
+ if (loopback_init()) {
+ printk(KERN_ERR "Network loopback device setup failed\n");
+ }
+
+
#ifdef CONFIG_SBNI
for (num = 0; num < 8; ++num)
if (sbni_probe())
@@ -477,18 +486,6 @@ static struct net_device dev_ltpc = {
#undef NEXT_DEV
#define NEXT_DEV (&dev_ltpc)
#endif /* LTPC */
-
-/*
- * The loopback device is global so it can be directly referenced
- * by the network code. Also, it must be first on device list.
- */
-
-extern int loopback_init(struct net_device *dev);
-struct net_device loopback_dev = {
- .name = "lo",
- .next = NEXT_DEV,
- .init = loopback_init
-};
/*
* The @dev_base list is protected by @dev_base_lock and the rtln
@@ -509,6 +506,6 @@ struct net_device loopback_dev = {
* unregister_netdevice(), which must be called with the rtnl
* semaphore held.
*/
-struct net_device *dev_base = &loopback_dev;
+struct net_device *dev_base;
rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 7382804af6b0..5dd2b3393edc 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -55,6 +55,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
+
#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
/* KISS: just allocate small chunks and copy bits.
@@ -152,10 +153,12 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->last_rx = jiffies;
- stats->rx_bytes+=skb->len;
- stats->tx_bytes+=skb->len;
- stats->rx_packets++;
- stats->tx_packets++;
+ if (likely(stats)) {
+ stats->rx_bytes+=skb->len;
+ stats->tx_bytes+=skb->len;
+ stats->rx_packets++;
+ stats->tx_packets++;
+ }
netif_rx(skb);
@@ -167,36 +170,35 @@ static struct net_device_stats *get_stats(struct net_device *dev)
return (struct net_device_stats *)dev->priv;
}
-/* Initialize the rest of the LOOPBACK device. */
-int __init loopback_init(struct net_device *dev)
-{
- dev->mtu = (16 * 1024) + 20 + 20 + 12;
- dev->hard_start_xmit = loopback_xmit;
- dev->hard_header = eth_header;
- dev->hard_header_cache = eth_header_cache;
- dev->header_cache_update= eth_header_cache_update;
- dev->hard_header_len = ETH_HLEN; /* 14 */
- dev->addr_len = ETH_ALEN; /* 6 */
- dev->tx_queue_len = 0;
- dev->type = ARPHRD_LOOPBACK; /* 0x0001 */
- dev->rebuild_header = eth_rebuild_header;
- dev->flags = IFF_LOOPBACK;
- dev->features = NETIF_F_SG|NETIF_F_FRAGLIST|NETIF_F_NO_CSUM|NETIF_F_HIGHDMA;
-
- /* Current netfilter will die with oom linearizing large skbs,
- * however this will be cured before 2.5.x is done.
- */
- dev->features |= NETIF_F_TSO;
-
- dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_device_stats));
- dev->get_stats = get_stats;
+struct net_device loopback_dev = {
+ .name = "lo",
+ .mtu = (16 * 1024) + 20 + 20 + 12,
+ .hard_start_xmit = loopback_xmit,
+ .hard_header = eth_header,
+ .hard_header_cache = eth_header_cache,
+ .header_cache_update = eth_header_cache_update,
+ .hard_header_len = ETH_HLEN, /* 14 */
+ .addr_len = ETH_ALEN, /* 6 */
+ .tx_queue_len = 0,
+ .type = ARPHRD_LOOPBACK, /* 0x0001*/
+ .rebuild_header = eth_rebuild_header,
+ .flags = IFF_LOOPBACK,
+ .features = NETIF_F_SG|NETIF_F_FRAGLIST
+ |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA|NETIF_F_TSO,
+};
- /*
- * Fill in the generic fields of the device structure.
- */
-
- return(0);
+/* Setup and register the of the LOOPBACK device. */
+int __init loopback_init(void)
+{
+ struct net_device_stats *stats;
+
+ /* Can survive without statistics */
+ stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+ if (stats) {
+ memset(stats, 0, sizeof(struct net_device_stats));
+ loopback_dev.priv = stats;
+ loopback_dev.get_stats = &get_stats;
+ }
+
+ return register_netdev(&loopback_dev);
};