summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@kernel.bkbits.net>2003-09-03 15:27:24 -0700
committerDavid S. Miller <davem@kernel.bkbits.net>2003-09-03 15:27:24 -0700
commita587017c337cc45fbb4eee26a80656af37150c19 (patch)
treecc7597e0b03e8e1a9f21e140272053d77d17c95d /drivers/net
parent6cea4e9ecabb8f3f07cdb60b17054549e591bc30 (diff)
parent874610601f16fa55e49ffc218e60c22aa42f759d (diff)
Merge nuts.ninka.net:/disk1/davem/BK/net-2.5
into kernel.bkbits.net:/home/davem/net-2.5
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c509.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c2
-rw-r--r--drivers/net/Space.c314
-rw-r--r--drivers/net/acenic.c10
-rwxr-xr-xdrivers/net/amd8111e.c2
-rw-r--r--drivers/net/appletalk/cops.c132
-rw-r--r--drivers/net/appletalk/ltpc.c251
-rw-r--r--drivers/net/b44.c2
-rw-r--r--drivers/net/bmac.c2
-rw-r--r--drivers/net/dgrs.c4
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/eepro100.c2
-rw-r--r--drivers/net/epic100.c2
-rw-r--r--drivers/net/fealnx.c2
-rw-r--r--drivers/net/hamachi.c2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/lasi_82596.c2
-rw-r--r--drivers/net/loopback.c72
-rw-r--r--drivers/net/lp486e.c2
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/pcnet32.c47
-rw-r--r--drivers/net/r8169.c4
-rw-r--r--drivers/net/rcpci45.c2
-rw-r--r--drivers/net/sb1000.c4
-rw-r--r--drivers/net/sis190.c15
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/smc-mca.c33
-rw-r--r--drivers/net/starfire.c2
-rw-r--r--drivers/net/sundance.c2
-rw-r--r--drivers/net/sungem.c33
-rw-r--r--drivers/net/sunhme.c4
-rw-r--r--drivers/net/sunqe.c2
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/net/tlan.c4
-rw-r--r--drivers/net/typhoon.c2
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/wan/dlci.c129
-rw-r--r--drivers/net/wan/sbni.c57
-rw-r--r--drivers/net/wan/sdla.c160
-rw-r--r--drivers/net/yellowfin.c2
41 files changed, 607 insertions, 718 deletions
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index df5f96439afa..74fd4100332b 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -604,7 +604,7 @@ out1:
pnp_device_detach(idev);
#endif
out:
- kfree(dev);
+ free_netdev(dev);
return err;
}
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 4e3eabe1e5ea..572de917454d 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1468,7 +1468,7 @@ free_ring:
free_region:
if (vp->must_free_region)
release_region(ioaddr, vci->io_size);
- kfree (dev);
+ free_netdev(dev);
printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
return retval;
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a49241c1ae23..fc3c04c6c7bc 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1768,7 +1768,7 @@ err_out_mwi:
err_out_disable:
pci_disable_device(pdev);
err_out_free:
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 46777c8dcf18..1963e60de0b2 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -32,14 +32,13 @@
*/
#include <linux/config.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/trdevice.h>
#include <linux/errno.h>
#include <linux/init.h>
#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...]".
*/
@@ -98,6 +97,15 @@ extern int macsonic_probe(struct net_device *dev);
extern int mac8390_probe(struct net_device *dev);
extern int mac89x0_probe(struct net_device *dev);
extern int mc32_probe(struct net_device *dev);
+#ifdef CONFIG_SDLA
+extern struct net_device *sdla_init(void);
+#endif
+#ifdef CONFIG_COPS
+extern struct net_device *cops_probe(int unit);
+#endif
+#ifdef CONFIG_LTPC
+extern struct net_device *ltpc_probe(void);
+#endif
/* Detachable devices ("pocket adaptors") */
extern int de620_probe(struct net_device *);
@@ -106,7 +114,7 @@ extern int de620_probe(struct net_device *);
extern int iph5526_probe(struct net_device *dev);
/* SBNI adapters */
-extern int sbni_probe(struct net_device *);
+extern int sbni_probe(void);
struct devprobe
{
@@ -352,124 +360,43 @@ static struct devprobe mips_probes[] __initdata = {
* per bus interface. This drives the legacy devices only for now.
*/
-static int __init ethif_probe(struct net_device *dev)
+static int __init ethif_probe(void)
{
- unsigned long base_addr = dev->base_addr;
+ struct net_device *dev;
+ int err = -ENODEV;
+
+ dev = alloc_etherdev(0);
+ if (!dev)
+ return -ENOMEM;
+
+ netdev_boot_setup_check(dev);
/*
* Backwards compatibility - historically an I/O base of 1 was
* used to indicate not to probe for this ethN interface
*/
- if (base_addr == 1)
- return 1; /* ENXIO */
+ if (dev->base_addr == 1) {
+ free_netdev(dev);
+ return -ENXIO;
+ }
/*
* The arch specific probes are 1st so that any on-board ethernet
* will be probed before other ISA/EISA/MCA/PCI bus cards.
*/
- if (probe_list(dev, m68k_probes) == 0)
- return 0;
- if (probe_list(dev, mips_probes) == 0)
- return 0;
- if (probe_list(dev, eisa_probes) == 0)
- return 0;
- if (probe_list(dev, mca_probes) == 0)
- return 0;
- if (probe_list(dev, isa_probes) == 0)
- return 0;
- if (probe_list(dev, parport_probes) == 0)
- return 0;
- return -ENODEV;
-}
-
-#ifdef CONFIG_SDLA
-extern int sdla_init(struct net_device *);
-static struct net_device sdla0_dev = {
- .name = "sdla0",
- .next = NEXT_DEV,
- .init = sdla_init,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&sdla0_dev)
-#endif
-
-#if defined(CONFIG_LTPC)
-extern int ltpc_probe(struct net_device *);
-static struct net_device dev_ltpc = {
- .name = "lt0",
- .next = NEXT_DEV,
- .init = ltpc_probe
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&dev_ltpc)
-#endif /* LTPC */
-
-#if defined(CONFIG_COPS)
-extern int cops_probe(struct net_device *);
-static struct net_device cops2_dev = {
- .name = "lt2",
- .next = NEXT_DEV,
- .init = cops_probe,
-};
-static struct net_device cops1_dev = {
- .name = "lt1",
- .next = &cops2_dev,
- .init = cops_probe,
-};
-static struct net_device cops0_dev = {
- .name = "lt0",
- .next = &cops1_dev,
- .init = cops_probe,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&cops0_dev)
-#endif /* COPS */
-
-static struct net_device eth7_dev = {
- .name = "eth%d",
- .next = NEXT_DEV,
- .init = ethif_probe,
-};
-static struct net_device eth6_dev = {
- .name = "eth%d",
- .next = &eth7_dev,
- .init = ethif_probe,
-};
-static struct net_device eth5_dev = {
- .name = "eth%d",
- .next = &eth6_dev,
- .init = ethif_probe,
-};
-static struct net_device eth4_dev = {
- .name = "eth%d",
- .next = &eth5_dev,
- .init = ethif_probe,
-};
-static struct net_device eth3_dev = {
- .name = "eth%d",
- .next = &eth4_dev,
- .init = ethif_probe,
-};
-static struct net_device eth2_dev = {
- .name = "eth%d",
- .next = &eth3_dev,
- .init = ethif_probe,
-};
-static struct net_device eth1_dev = {
- .name = "eth%d",
- .next = &eth2_dev,
- .init = ethif_probe,
-};
-static struct net_device eth0_dev = {
- .name = "eth%d",
- .next = &eth1_dev,
- .init = ethif_probe,
-};
-
-#undef NEXT_DEV
-#define NEXT_DEV (&eth0_dev)
-
+ if (probe_list(dev, m68k_probes) == 0 ||
+ probe_list(dev, mips_probes) == 0 ||
+ probe_list(dev, eisa_probes) == 0 ||
+ probe_list(dev, mca_probes) == 0 ||
+ probe_list(dev, isa_probes) == 0 ||
+ probe_list(dev, parport_probes) == 0)
+ err = register_netdev(dev);
+
+ if (err)
+ free_netdev(dev);
+ return err;
+}
#ifdef CONFIG_TR
/* Token-ring device probe */
@@ -478,129 +405,82 @@ extern int sk_isa_probe(struct net_device *);
extern int proteon_probe(struct net_device *);
extern int smctr_probe(struct net_device *);
-static int
-trif_probe(struct net_device *dev)
+static __init int trif_probe(void)
{
- if (1
+ struct net_device *dev;
+ int err = -ENODEV;
+
+ dev = alloc_trdev(0);
+ if (!dev)
+ return -ENOMEM;
+
+ netdev_boot_setup_check(dev);
+ if (
#ifdef CONFIG_IBMTR
- && ibmtr_probe(dev)
+ ibmtr_probe(dev) == 0 ||
#endif
#ifdef CONFIG_SKISA
- && sk_isa_probe(dev)
+ sk_isa_probe(dev) == 0 ||
#endif
#ifdef CONFIG_PROTEON
- && proteon_probe(dev)
+ proteon_probe(dev) == 0 ||
#endif
#ifdef CONFIG_SMCTR
- && smctr_probe(dev)
+ smctr_probe(dev) == 0 ||
#endif
- && 1 ) {
- return 1; /* -ENODEV or -EAGAIN would be more accurate. */
- }
- return 0;
-}
-static struct net_device tr7_dev = {
- .name = "tr%d",
- .next = NEXT_DEV,
- .init = trif_probe,
-};
-static struct net_device tr6_dev = {
- .name = "tr%d",
- .next = &tr7_dev,
- .init = trif_probe,
-};
-static struct net_device tr5_dev = {
- .name = "tr%d",
- .next = &tr6_dev,
- .init = trif_probe,
-};
-static struct net_device tr4_dev = {
- .name = "tr%d",
- .next = &tr5_dev,
- .init = trif_probe,
-};
-static struct net_device tr3_dev = {
- .name = "tr%d",
- .next = &tr4_dev,
- .init = trif_probe,
-};
-static struct net_device tr2_dev = {
- .name = "tr%d",
- .next = &tr3_dev,
- .init = trif_probe,
-};
-static struct net_device tr1_dev = {
- .name = "tr%d",
- .next = &tr2_dev,
- .init = trif_probe,
-};
-static struct net_device tr0_dev = {
- .name = "tr%d",
- .next = &tr1_dev,
- .init = trif_probe,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&tr0_dev)
+ 0 )
+ err = register_netdev(dev);
+
+ if (err)
+ free_netdev(dev);
+ return err;
-#endif
-
-#ifdef CONFIG_SBNI
-static struct net_device sbni7_dev = {
- .name = "sbni7",
- .next = NEXT_DEV,
- .init = sbni_probe,
-};
-static struct net_device sbni6_dev = {
- .name = "sbni6",
- .next = &sbni7_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni5_dev = {
- .name = "sbni5",
- .next = &sbni6_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni4_dev = {
- .name = "sbni4",
- .next = &sbni5_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni3_dev = {
- .name = "sbni3",
- .next = &sbni4_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni2_dev = {
- .name = "sbni2",
- .next = &sbni3_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni1_dev = {
- .name = "sbni1",
- .next = &sbni2_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni0_dev = {
- .name = "sbni0",
- .next = &sbni1_dev,
- .init = sbni_probe,
-};
+}
+#endif
-#undef NEXT_DEV
-#define NEXT_DEV (&sbni0_dev)
-#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);
-extern int loopback_init(struct net_device *dev);
-struct net_device loopback_dev = {
- .name = "lo",
- .next = NEXT_DEV,
- .init = loopback_init
-};
+/* 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())
+ break;
+#endif
+#ifdef CONFIG_TR
+ for (num = 0; num < 8; ++num)
+ if (trif_probe())
+ break;
+#endif
+ for (num = 0; num < 8; ++num)
+ if (ethif_probe())
+ break;
+#ifdef CONFIG_COPS
+ cops_probe(0);
+ cops_probe(1);
+ cops_probe(2);
+#endif
+#ifdef CONFIG_LTPC
+ ltpc_probe();
+#endif
+#ifdef CONFIG_SDLA
+ sdla_init();
+#endif
+
+}
/*
* The @dev_base list is protected by @dev_base_lock and the rtln
@@ -621,6 +501,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/acenic.c b/drivers/net/acenic.c
index d6a4fdcec957..3350a70c2103 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -685,7 +685,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
}
if (pci_enable_device(pdev)) {
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -733,7 +733,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
if (register_netdev(dev)) {
printk(KERN_ERR "acenic: device registration failed\n");
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -793,7 +793,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
printk(KERN_ERR "%s: Driver compiled without Tigon I"
" support - NIC disabled\n", dev->name);
ace_init_cleanup(dev);
- kfree(dev);
+ free_netdev(dev);
continue;
}
#endif
@@ -803,7 +803,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
* ace_allocate_descriptors() calls
* ace_init_cleanup() on error.
*/
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -820,7 +820,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
/*
* ace_init() calls ace_init_cleanup() on error.
*/
- kfree(dev);
+ free_netdev(dev);
continue;
}
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 19464a83fdfb..bc9e1bfc7220 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1927,7 +1927,7 @@ err_iounmap:
iounmap((void *) lp->mmio);
err_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_free_reg:
pci_release_regions(pdev);
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index cb8dac24f286..579cf0d2ee5b 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -92,12 +92,8 @@ static int board_type = DAYNA; /* Module exported */
static int board_type = TANGENT;
#endif
-#ifdef MODULE
static int io = 0x240; /* Default IO for Dayna */
static int irq = 5; /* Default IRQ */
-#else
-static int io; /* Default IO for Dayna */
-#endif
/*
* COPS Autoprobe information.
@@ -146,7 +142,7 @@ static int io; /* Default IO for Dayna */
* Zero terminated list of IO ports to probe.
*/
-static unsigned int cops_portlist[] = {
+static unsigned int ports[] = {
0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
0
@@ -184,7 +180,6 @@ struct cops_local
};
/* Index to functions, as function prototypes. */
-extern int cops_probe (struct net_device *dev);
static int cops_probe1 (struct net_device *dev, int ioaddr);
static int cops_irq (int ioaddr, int board);
@@ -208,6 +203,12 @@ static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev);
static struct net_device_stats *cops_get_stats (struct net_device *dev);
+static void cleanup_card(struct net_device *dev)
+{
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, COPS_IO_EXTENT);
+}
/*
* Check for a network adaptor of this type, and return '0' iff one exists.
@@ -215,31 +216,54 @@ static struct net_device_stats *cops_get_stats (struct net_device *dev);
* If dev->base_addr in [1..0x1ff], always return failure.
* otherwise go with what we pass in.
*/
-int __init cops_probe(struct net_device *dev)
+struct net_device * __init cops_probe(int unit)
{
- int i;
- int base_addr = dev->base_addr;
+ struct net_device *dev;
+ unsigned *port;
+ int base_addr;
+ int err = 0;
+
+ dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ if (unit >= 0) {
+ sprintf(dev->name, "lt%d", unit);
+ netdev_boot_setup_check(dev);
+ irq = dev->irq;
+ base_addr = dev->base_addr;
+ } else {
+ base_addr = dev->base_addr = io;
+ }
SET_MODULE_OWNER(dev);
- if(base_addr == 0 && io)
- base_addr=io;
-
- if(base_addr > 0x1ff) /* Check a single specified location. */
- return cops_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- /* FIXME Does this really work for cards which generate irq?
- * It's definitely N.G. for polled Tangent. sh
- * Dayna cards don't autoprobe well at all, but if your card is
- * at IRQ 5 & IO 0x240 we find it every time. ;) JS
- */
- for(i=0; cops_portlist[i]; i++)
- if(cops_probe1(dev, cops_portlist[i]) == 0)
- return 0;
-
- return -ENODEV;
+ if (base_addr > 0x1ff) { /* Check a single specified location. */
+ err = cops_probe1(dev, base_addr);
+ } else if (base_addr != 0) { /* Don't probe at all. */
+ err = -ENXIO;
+ } else {
+ /* FIXME Does this really work for cards which generate irq?
+ * It's definitely N.G. for polled Tangent. sh
+ * Dayna cards don't autoprobe well at all, but if your card is
+ * at IRQ 5 & IO 0x240 we find it every time. ;) JS
+ */
+ for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
+ ;
+ if (!*port)
+ err = -ENODEV;
+ }
+ if (err)
+ goto out;
+ err = register_netdev(dev);
+ if (err)
+ goto out1;
+ return dev;
+out1:
+ cleanup_card(dev);
+out:
+ kfree(dev);
+ return ERR_PTR(err);
}
/*
@@ -268,16 +292,15 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
* interrupts are typically not reported by the boards, and we must
* used AutoIRQ to find them.
*/
+ dev->irq = irq;
switch (dev->irq)
{
case 0:
/* COPS AutoIRQ routine */
dev->irq = cops_irq(ioaddr, board);
- if(!dev->irq) {
- retval = -EINVAL; /* No IRQ found on this port */
- goto err_out;
- }
-
+ if (dev->irq)
+ break;
+ /* No IRQ found on this port, fallthrough */
case 1:
retval = -EINVAL;
goto err_out;
@@ -302,22 +325,13 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
}
/* Reserve any actual interrupt. */
- if(dev->irq) {
+ if (dev->irq) {
retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
if (retval)
goto err_out;
}
- dev->base_addr = ioaddr;
-
- /* Initialize the private device structure. */
- dev->priv = kmalloc(sizeof(struct cops_local), GFP_KERNEL);
- if(dev->priv == NULL) {
- if (dev->irq)
- free_irq(dev->irq, dev);
- retval = -ENOMEM;
- goto err_out;
- }
+ dev->base_addr = ioaddr;
lp = (struct cops_local *)dev->priv;
memset(lp, 0, sizeof(struct cops_local));
@@ -326,9 +340,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Copy local board variable to lp struct. */
lp->board = board;
- /* Fill in the fields of the device structure with LocalTalk values. */
- ltalk_setup(dev);
-
dev->hard_start_xmit = cops_send_packet;
dev->tx_timeout = cops_timeout;
dev->watchdog_timeo = HZ * 2;
@@ -1013,7 +1024,7 @@ static struct net_device_stats *cops_get_stats(struct net_device *dev)
}
#ifdef MODULE
-static struct net_device cops0_dev = { .init = cops_probe };
+static struct net_device *cops_dev;
MODULE_LICENSE("GPL");
MODULE_PARM(io, "i");
@@ -1022,33 +1033,20 @@ MODULE_PARM(board_type, "i");
int init_module(void)
{
- int result, err;
-
- if(io == 0)
+ if (io == 0)
printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
cardname);
-
- /* Copy the parameters from insmod into the device structure. */
- cops0_dev.base_addr = io;
- cops0_dev.irq = irq;
-
- err=dev_alloc_name(&cops0_dev, "lt%d");
- if(err < 0)
- return err;
-
- if((result = register_netdev(&cops0_dev)) != 0)
- return result;
-
+ cops_dev = cops_probe(-1);
+ if (IS_ERR(cops_dev))
+ return PTR_ERR(cops_dev);
return 0;
}
void cleanup_module(void)
{
- unregister_netdev(&cops0_dev);
- kfree(cops0_dev.priv);
- if(cops0_dev.irq)
- free_irq(cops0_dev.irq, &cops0_dev);
- release_region(cops0_dev.base_addr, COPS_IO_EXTENT);
+ unregister_netdev(cops_dev);
+ cleanup_card(cops_dev);
+ free_netdev(cops_dev);
}
#endif /* MODULE */
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index ddbd4f765b12..1b10bc14867c 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -879,34 +879,6 @@ static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev,
return 0;
}
-static int ltpc_init(struct net_device *dev)
-{
- /* Initialize the device structure. */
-
- /* Fill in the fields of the device structure with ethernet-generic values. */
- ltalk_setup(dev);
- dev->hard_start_xmit = ltpc_xmit;
- dev->hard_header = ltpc_hard_header;
-
- dev->priv = kmalloc(sizeof(struct ltpc_private), GFP_KERNEL);
- if(!dev->priv)
- {
- printk(KERN_INFO "%s: could not allocate statistics buffer\n", dev->name);
- return -ENOMEM;
- }
-
- memset(dev->priv, 0, sizeof(struct ltpc_private));
- dev->get_stats = ltpc_get_stats;
-
- /* add the ltpc-specific things */
- dev->do_ioctl = &ltpc_ioctl;
-
- dev->set_multicast_list = &set_multicast_list;
- dev->mc_list = NULL;
-
- return 0;
-}
-
static int ltpc_poll_counter;
static void ltpc_poll(unsigned long l)
@@ -983,35 +955,40 @@ static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
/* initialization stuff */
-static int __init ltpc_probe_dma(int base)
+static int __init ltpc_probe_dma(int base, int dma)
{
- int dma = 0;
+ int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3;
unsigned long timeout;
unsigned long f;
- if (!request_dma(1,"ltpc")) {
- f=claim_dma_lock();
- disable_dma(1);
- clear_dma_ff(1);
- set_dma_mode(1,DMA_MODE_WRITE);
- set_dma_addr(1,virt_to_bus(ltdmabuf));
- set_dma_count(1,sizeof(struct lt_mem));
- enable_dma(1);
- release_dma_lock(f);
- dma|=1;
+ if (want & 1) {
+ if (request_dma(1,"ltpc")) {
+ want &= ~1;
+ } else {
+ f=claim_dma_lock();
+ disable_dma(1);
+ clear_dma_ff(1);
+ set_dma_mode(1,DMA_MODE_WRITE);
+ set_dma_addr(1,virt_to_bus(ltdmabuf));
+ set_dma_count(1,sizeof(struct lt_mem));
+ enable_dma(1);
+ release_dma_lock(f);
+ }
}
- if (!request_dma(3,"ltpc")) {
- f=claim_dma_lock();
- disable_dma(3);
- clear_dma_ff(3);
- set_dma_mode(3,DMA_MODE_WRITE);
- set_dma_addr(3,virt_to_bus(ltdmabuf));
- set_dma_count(3,sizeof(struct lt_mem));
- enable_dma(3);
- release_dma_lock(f);
- dma|=2;
+ if (want & 2) {
+ if (request_dma(3,"ltpc")) {
+ want &= ~2;
+ } else {
+ f=claim_dma_lock();
+ disable_dma(3);
+ clear_dma_ff(3);
+ set_dma_mode(3,DMA_MODE_WRITE);
+ set_dma_addr(3,virt_to_bus(ltdmabuf));
+ set_dma_count(3,sizeof(struct lt_mem));
+ enable_dma(3);
+ release_dma_lock(f);
+ }
}
-
/* set up request */
/* FIXME -- do timings better! */
@@ -1037,65 +1014,62 @@ static int __init ltpc_probe_dma(int base)
/* release the other dma channel (if we opened both of them) */
- if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){
- dma&=1;
+ if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) {
+ want &= ~2;
free_dma(3);
}
-
- if ( (dma&0x1) && (get_dma_residue(1)==sizeof(struct lt_mem)) ){
- dma&=0x2;
+
+ if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) {
+ want &= ~1;
free_dma(1);
}
- /* fix up dma number */
- dma|=1;
+ if (!want)
+ return 0;
- return dma;
+ return (want & 2) ? 3 : 1;
}
-int __init ltpc_probe(struct net_device *dev)
+struct net_device * __init ltpc_probe(void)
{
- int err;
+ struct net_device *dev;
+ int err = -ENOMEM;
int x=0,y=0;
int autoirq;
unsigned long f;
- int portfound=0;
unsigned long timeout;
+ dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup);
+ if (!dev)
+ goto out;
+
SET_MODULE_OWNER(dev);
/* probe for the I/O port address */
+
if (io != 0x240 && request_region(0x220,8,"ltpc")) {
x = inb_p(0x220+6);
if ( (x!=0xff) && (x>=0xf0) ) {
io = 0x220;
- portfound=1;
- }
- else {
- release_region(0x220,8);
+ goto got_port;
}
+ release_region(0x220,8);
}
-
if (io != 0x220 && request_region(0x240,8,"ltpc")) {
y = inb_p(0x240+6);
if ( (y!=0xff) && (y>=0xf0) ){
io = 0x240;
- portfound=1;
- }
- else {
- release_region(0x240,8);
+ goto got_port;
}
+ release_region(0x240,8);
}
- if(io && !portfound && request_region(io,8,"ltpc")){
- portfound = 1;
- }
- if(!portfound) {
- /* give up in despair */
- printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y);
- return -1;
- }
+ /* give up in despair */
+ printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y);
+ err = -ENODEV;
+ goto out1;
+ got_port:
/* probe for the IRQ line */
if (irq < 2) {
unsigned long irq_mask;
@@ -1111,22 +1085,21 @@ int __init ltpc_probe(struct net_device *dev)
if (autoirq == 0) {
printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io);
- }
- else {
+ } else {
irq = autoirq;
}
}
/* allocate a DMA buffer */
ltdmabuf = (unsigned char *) dma_mem_alloc(1000);
-
- if (ltdmabuf) ltdmacbuf = &ltdmabuf[800];
-
if (!ltdmabuf) {
printk(KERN_ERR "ltpc: mem alloc failed\n");
- return -1;
+ err = -ENOMEM;
+ goto out2;
}
+ ltdmacbuf = &ltdmabuf[800];
+
if(debug & DEBUG_VERBOSE) {
printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf);
}
@@ -1154,25 +1127,29 @@ int __init ltpc_probe(struct net_device *dev)
already been specified */
/* well, 0 is a legal DMA channel, but the LTPC card doesn't
use it... */
- if (dma == 0) {
- dma = ltpc_probe_dma(io);
- if (!dma) { /* no dma channel */
- printk(KERN_ERR "No DMA channel found on ltpc card.\n");
- return -1;
- }
+ dma = ltpc_probe_dma(io, dma);
+ if (!dma) { /* no dma channel */
+ printk(KERN_ERR "No DMA channel found on ltpc card.\n");
+ err = -ENODEV;
+ goto out3;
}
/* print out friendly message */
-
if(irq)
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma);
else
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
- /* seems more logical to do this *after* probing the card... */
- err = ltpc_init(dev);
- if (err) return err;
+ /* Fill in the fields of the device structure with ethernet-generic values. */
+ dev->hard_start_xmit = ltpc_xmit;
+ dev->hard_header = ltpc_hard_header;
+ dev->get_stats = ltpc_get_stats;
+ /* add the ltpc-specific things */
+ dev->do_ioctl = &ltpc_ioctl;
+
+ dev->set_multicast_list = &set_multicast_list;
+ dev->mc_list = NULL;
dev->base_addr = io;
dev->irq = irq;
dev->dma = dma;
@@ -1212,6 +1189,7 @@ int __init ltpc_probe(struct net_device *dev)
} else {
if( irq )
printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n");
+ dev->irq = 0;
/* polled mode -- 20 times per second */
/* this is really, really slow... should it poll more often? */
init_timer(&ltpc_timer);
@@ -1221,8 +1199,23 @@ int __init ltpc_probe(struct net_device *dev)
ltpc_timer.expires = jiffies + HZ/20;
add_timer(&ltpc_timer);
}
+ err = register_netdev(dev);
+ if (err)
+ goto out4;
return 0;
+out4:
+ del_timer_sync(&ltpc_timer);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+out3:
+ free_pages((unsigned long)ltdmabuf, get_order(1000));
+out2:
+ release_region(io, 8);
+out1:
+ kfree(dev);
+out:
+ return ERR_PTR(err);
}
#ifndef MODULE
@@ -1259,7 +1252,7 @@ static int __init ltpc_setup(char *str)
__setup("ltpc=", ltpc_setup);
#endif /* MODULE */
-static struct net_device dev_ltpc;
+static struct net_device *dev_ltpc;
#ifdef MODULE
@@ -1272,79 +1265,47 @@ MODULE_PARM(dma, "i");
int __init init_module(void)
{
- int err, result;
-
if(io == 0)
printk(KERN_NOTICE
"ltpc: Autoprobing is not recommended for modules\n");
- /* Find a name for this unit */
- dev_ltpc.init = ltpc_probe;
- err=dev_alloc_name(&dev_ltpc,"lt%d");
-
- if(err<0)
- return err;
-
- if ((result = register_netdev(&dev_ltpc)) != 0) {
- printk(KERN_DEBUG "could not register Localtalk-PC device\n");
- return result;
- } else {
- if(debug & DEBUG_VERBOSE) printk("0 from register_netdev\n");
- return 0;
- }
+ dev_ltpc = ltpc_probe();
+ if (IS_ERR(dev_ltpc))
+ return PTR_ERR(dev_ltpc);
+ return 0;
}
#endif
static void __exit ltpc_cleanup(void)
{
- unsigned long timeout;
+
+ if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
+ unregister_netdev(dev_ltpc);
ltpc_timer.data = 0; /* signal the poll routine that we're done */
+ del_timer_sync(&ltpc_timer);
+
if(debug & DEBUG_VERBOSE) printk("freeing irq\n");
- if(dev_ltpc.irq) {
- free_irq(dev_ltpc.irq,&dev_ltpc);
- dev_ltpc.irq = 0;
- }
-
- if(del_timer(&ltpc_timer))
- {
- /* either the poll was never started, or a poll is in process */
- if(debug & DEBUG_VERBOSE) printk("waiting\n");
- /* if it's in process, wait a bit for it to finish */
- timeout = jiffies+HZ;
- add_timer(&ltpc_timer);
- while(del_timer(&ltpc_timer) && time_after(timeout, jiffies))
- {
- add_timer(&ltpc_timer);
- schedule();
- }
- }
+ if (dev_ltpc->irq)
+ free_irq(dev_ltpc->irq, dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("freeing dma\n");
- if(dev_ltpc.dma) {
- free_dma(dev_ltpc.dma);
- dev_ltpc.dma = 0;
- }
+ if (dev_ltpc->dma)
+ free_dma(dev_ltpc->dma);
if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n");
- if(dev_ltpc.base_addr) {
- release_region(dev_ltpc.base_addr,8);
- dev_ltpc.base_addr = 0;
- }
+ if (dev_ltpc->base_addr)
+ release_region(dev_ltpc->base_addr,8);
+
+ free_netdev(dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("free_pages\n");
free_pages( (unsigned long) ltdmabuf, get_order(1000));
- ltdmabuf=NULL;
- ltdmacbuf=NULL;
-
- if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
-
- unregister_netdev(&dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n");
}
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index b759af47913d..ef10d16fd679 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1834,7 +1834,7 @@ err_out_iounmap:
iounmap((void *) bp->regs);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_free_res:
pci_release_regions(pdev);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index ed7874f4fe4e..27bc8ed937cf 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1462,7 +1462,7 @@ out2:
release_OF_resource(bp->node, 0);
out1:
pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
- kfree(dev);
+ free_netdev(dev);
}
static int bmac_open(struct net_device *dev)
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 00ddd19e0fd2..d28d864cbaa5 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1275,7 +1275,7 @@ dgrs_found_device(
SET_MODULE_OWNER(dev);
if (register_netdev(dev) != 0) {
- kfree(dev);
+ free_netdev(dev);
return -EIO;
}
@@ -1322,7 +1322,7 @@ dgrs_found_device(
ret = -EIO;
if (register_netdev(devN)) {
- kfree(devN);
+ free_netdev(devN);
goto fail;
}
privN->chan = i+1;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index d0fba4cb4df4..76f1d66eb6c1 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -319,7 +319,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_dev:
#endif
- kfree (dev);
+ free_netdev (dev);
err_out_res:
pci_release_regions (pdev);
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 2a14f46f6014..02c2db84f603 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -894,7 +894,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
err_free_unlock:
rtnl_unlock();
- kfree(dev);
+ free_netdev(dev);
return -1;
}
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 93fdb1469a0c..00bbf4b7baea 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -565,7 +565,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
return -ENODEV;
}
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index de914dfc56f8..ee1e45180f86 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -689,7 +689,7 @@ err_out_free_tx:
err_out_free_rx:
pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_unmap:
#ifndef USE_IO_OPS
iounmap((void *)ioaddr);
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 36e7074c2bd8..ab87588a7ff3 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -785,7 +785,7 @@ err_out_unmap_tx:
pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring,
hmp->tx_ring_dma);
err_out_cleardev:
- kfree (dev);
+ free_netdev (dev);
err_out_iounmap:
iounmap((char *)ioaddr);
err_out_release:
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index c3b4e5f1353d..d93767489ff0 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1512,7 +1512,7 @@ out_stop:
out_res:
pci_release_regions(pdev);
out_free:
- kfree(dev);
+ free_netdev(dev);
return err;
}
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index b3045c467da8..6f8c223bf68e 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -1543,7 +1543,7 @@ lan_init_chip(struct parisc_device *dev)
retval = register_netdev(netdevice);
if (retval) {
printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval);
- kfree(netdevice);
+ free_netdev(netdevice);
return -ENODEV;
};
if (dev->id.sversion == 0x72) {
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);
};
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index fe1e255a576c..3e687d9cbd41 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -1324,7 +1324,7 @@ static int __init lp486e_init_module(void) {
dev->base_addr = io;
dev->init = lp486e_probe;
if (register_netdev(dev) != 0) {
- kfree(dev);
+ free_netdev(dev);
return -EIO;
}
dev_lp486e = dev;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index b95d3030e465..14fbbef63fb6 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -766,7 +766,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
i = pci_request_regions(pdev, dev->name);
if (i) {
- kfree(dev);
+ free_netdev(dev);
return i;
}
@@ -774,7 +774,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
void *mmio = ioremap (ioaddr, iosize);
if (!mmio) {
pci_release_regions(pdev);
- kfree(dev);
+ free_netdev(dev);
return -ENOMEM;
}
ioaddr = (unsigned long) mmio;
@@ -838,7 +838,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
if (i) {
pci_release_regions(pdev);
unregister_netdev(dev);
- kfree(dev);
+ free_netdev(dev);
pci_set_drvdata(pdev, NULL);
return i;
}
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index ad6281ef7a83..2d519b696533 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -529,6 +529,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
struct net_device *dev;
struct pcnet32_access *a = NULL;
u8 promaddr[6];
+ int ret = -ENODEV;
/* reset the chip */
pcnet32_wio_reset(ioaddr);
@@ -540,19 +541,15 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
pcnet32_dwio_reset(ioaddr);
if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
a = &pcnet32_dwio;
- } else {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
- }
+ } else
+ goto err_release_region;
}
chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16);
if (pcnet32_debug > 2)
printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version);
- if ((chip_version & 0xfff) != 0x003) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
- }
+ if ((chip_version & 0xfff) != 0x003)
+ goto err_release_region;
/* initialize variables */
fdx = mii = fset = dxsuflo = ltint = 0;
@@ -614,8 +611,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
default:
printk(KERN_INFO PFX "PCnet version %#x, no PCnet32 chip.\n",
chip_version);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ goto err_release_region;
}
/*
@@ -635,8 +631,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
dev = alloc_etherdev(0);
if(!dev) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_release_region;
}
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -708,8 +704,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
dev->base_addr = ioaddr;
/* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_free_netdev;
}
memset(lp, 0, sizeof(*lp));
@@ -741,9 +737,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
if (!a) {
printk(KERN_ERR PFX "No access methods\n");
- pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_free_consistent;
}
lp->a = *a;
@@ -785,14 +780,12 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
mdelay (1);
dev->irq = probe_irq_off (irq_mask);
- if (dev->irq)
- printk(", probed IRQ %d.\n", dev->irq);
- else {
+ if (!dev->irq) {
printk(", failed to detect IRQ line.\n");
- pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_free_consistent;
}
+ printk(", probed IRQ %d.\n", dev->irq);
}
/* Set the mii phy_id so that we can query the link state */
@@ -821,6 +814,14 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name);
cards_found++;
return 0;
+
+err_free_consistent:
+ pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+err_free_netdev:
+ free_netdev(dev);
+err_release_region:
+ release_region(ioaddr, PCNET32_TOTAL_SIZE);
+ return ret;
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a0b4b659aa0e..c11b83e6adeb 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -454,7 +454,7 @@ err_out_disable:
pci_disable_device(pdev);
err_out:
- kfree(dev);
+ free_netdev(dev);
return rc;
}
@@ -514,7 +514,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ioaddr);
pci_release_regions(pdev);
pci_disable_device(pdev);
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
index f5cdead40f14..e7e1a9f2d71a 100644
--- a/drivers/net/rcpci45.c
+++ b/drivers/net/rcpci45.c
@@ -269,7 +269,7 @@ err_out_free_msgbuf:
pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf,
pDpa->msgbuf_dma);
err_out_free_dev:
- kfree (dev);
+ free_netdev (dev);
err_out:
card_idx--;
return error;
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index d0153f60a036..5326dee62c74 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -213,9 +213,11 @@ sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id)
error = register_netdev(dev);
if (error)
- goto out_release_regions;
+ goto out_free_netdev;
return 0;
+ out_free_netdev:
+ free_netdev(dev);
out_release_regions:
release_region(ioaddr[1], 16);
out_release_region0:
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 1c79e7b9c34e..9f421480b233 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -470,7 +470,7 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
rc = pci_set_dma_mask(pdev, 0xffffffffULL);
if (rc)
- goto err_out;
+ goto err_out_disable;
mmio_start = pci_resource_start(pdev, 0);
mmio_end = pci_resource_end(pdev, 0);
@@ -482,18 +482,18 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
printk(KERN_ERR PFX
"region #0 not an MMIO resource, aborting\n");
rc = -ENODEV;
- goto err_out;
+ goto err_out_disable;
}
// check for weird/broken PCI region reporting
if (mmio_len < SiS190_MIN_IO_SIZE) {
printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
rc = -ENODEV;
- goto err_out;
+ goto err_out_disable;
}
rc = pci_request_regions(pdev, dev->name);
if (rc)
- goto err_out;
+ goto err_out_disable;
// enable PCI bus-mastering
pci_set_master(pdev);
@@ -521,9 +521,10 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
err_out_free_res:
pci_release_regions(pdev);
-err_out:
+err_out_disable:
pci_disable_device(pdev);
- kfree(dev);
+err_out:
+ free_netdev(dev);
return rc;
}
@@ -603,7 +604,7 @@ SiS190_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ioaddr);
pci_release_regions(pdev);
pci_disable_device(pdev);
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index b5853f1a9fbd..6422eb2a4208 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -503,7 +503,7 @@ static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_dev
pci_set_drvdata(pci_dev, NULL);
pci_release_regions(pci_dev);
err_out:
- kfree(net_dev);
+ free_netdev(net_dev);
return ret;
}
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index e33c7a2a2f7f..c5a085707302 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -132,7 +132,7 @@ int __init ultramca_probe(struct device *gen_dev)
struct mca_device *mca_dev = to_mca_device(gen_dev);
char slot = mca_dev->slot;
unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
- int i;
+ int i, rc;
int adapter = mca_dev->index;
int tbase = 0;
int tirq = 0;
@@ -209,8 +209,9 @@ int __init ultramca_probe(struct device *gen_dev)
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, gen_dev);
- if((i = register_netdev(dev)) != 0)
- return i;
+ rc = register_netdev(dev);
+ if (rc)
+ goto err_free_netdev;
printk(KERN_INFO "%s: %s found in slot %d\n",
dev->name, smc_mca_adapter_names[adapter], slot + 1);
@@ -262,11 +263,15 @@ int __init ultramca_probe(struct device *gen_dev)
}
}
- if (dev->mem_start == 0) /* sanity check, shouldn't happen */
- return -ENODEV;
+ /* sanity check, shouldn't happen */
+ if (dev->mem_start == 0) {
+ rc = -ENODEV;
+ goto err_unregister_netdev;
+ }
- if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name))
- return -EBUSY;
+ rc = request_region(ioaddr, ULTRA_IO_EXTENT, dev->name);
+ if (rc)
+ goto err_unregister_netdev;
reg4 = inb(ioaddr + 4) & 0x7f;
outb(reg4, ioaddr + 4);
@@ -296,10 +301,10 @@ int __init ultramca_probe(struct device *gen_dev)
/* Allocate dev->priv and fill in 8390 specific dev fields.
*/
- if (ethdev_init(dev)) {
+ rc = ethdev_init(dev);
+ if (rc) {
printk (", no memory for dev->priv.\n");
- release_region(ioaddr, ULTRA_IO_EXTENT);
- return -ENOMEM;
+ goto err_release_region;
}
gen_dev->driver_data = dev;
@@ -334,6 +339,14 @@ int __init ultramca_probe(struct device *gen_dev)
NS8390_init(dev, 0);
return 0;
+
+err_release_region:
+ release_region(ioaddr, ULTRA_IO_EXTENT);
+err_unregister_netdev:
+ unregister_netdev(dev);
+err_free_netdev:
+ free_netdev(dev);
+ return rc;
}
static int ultramca_open(struct net_device *dev)
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index dcf1db7ea6ef..c2bddf1f1700 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1070,7 +1070,7 @@ err_out_cleardev:
err_out_free_res:
pci_release_regions (pdev);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
return -ENODEV;
}
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 5bd8be316547..aad877c5400b 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -734,7 +734,7 @@ err_out_res:
#endif
pci_release_regions(pdev);
err_out_netdev:
- kfree (dev);
+ free_netdev (dev);
return -ENODEV;
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index a452e5942b52..a346fd1d4dba 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2416,13 +2416,6 @@ static int gem_nway_reset(struct net_device *dev)
return 0;
}
-static u32 gem_get_link(struct net_device *dev)
-{
- struct gem *gp = dev->priv;
-
- return (gp->lstate == link_up);
-}
-
static u32 gem_get_msglevel(struct net_device *dev)
{
struct gem *gp = dev->priv;
@@ -2441,7 +2434,6 @@ static struct ethtool_ops gem_ethtool_ops = {
.get_settings = gem_get_settings,
.set_settings = gem_set_settings,
.nway_reset = gem_nway_reset,
- .get_link = gem_get_link,
.get_msglevel = gem_get_msglevel,
.set_msglevel = gem_set_msglevel,
};
@@ -2630,7 +2622,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
- return err;
+ goto err_disable_device;
}
pci_using_dac = 0;
}
@@ -2641,20 +2633,23 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
printk(KERN_ERR PFX "Cannot find proper PCI device "
"base address, aborting.\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto err_disable_device;
}
dev = alloc_etherdev(sizeof(*gp));
if (!dev) {
printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_disable_device;
}
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
gp = dev->priv;
- if (pci_request_regions(pdev, dev->name)) {
+ err = pci_request_regions(pdev, dev->name);
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources, "
"aborting.\n");
goto err_out_free_netdev;
@@ -2688,6 +2683,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (gp->regs == 0UL) {
printk(KERN_ERR PFX "Cannot map device registers, "
"aborting.\n");
+ err = -EIO;
goto err_out_free_res;
}
@@ -2711,8 +2707,10 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
/* By default, we start with autoneg */
gp->want_autoneg = 1;
- if (gem_check_invariants(gp))
+ if (gem_check_invariants(gp)) {
+ err = -ENODEV;
goto err_out_iounmap;
+ }
/* It is guaranteed that the returned buffer will be at least
* PAGE_SIZE aligned.
@@ -2723,6 +2721,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (!gp->init_block) {
printk(KERN_ERR PFX "Cannot allocate init block, "
"aborting.\n");
+ err = -ENOMEM;
goto err_out_iounmap;
}
@@ -2735,6 +2734,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (register_netdev(dev)) {
printk(KERN_ERR PFX "Cannot register net device, "
"aborting.\n");
+ err = -ENOMEM;
goto err_out_free_consistent;
}
@@ -2804,9 +2804,10 @@ err_out_free_res:
pci_release_regions(pdev);
err_out_free_netdev:
- kfree(dev);
-
- return -ENODEV;
+ free_netdev(dev);
+err_disable_device:
+ pci_disable_device(pdev);
+ return err;
}
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 8c786ab7b3c5..b91f7d0199bf 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2895,7 +2895,7 @@ err_out_iounmap:
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
err_out:
return err;
@@ -3247,7 +3247,7 @@ err_out_clear_quattro:
if (qp != NULL)
qp->happy_meals[qfe_slot] = NULL;
- kfree(dev);
+ free_netdev(dev);
err_out:
return err;
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index b5d8879c2035..5116b5152e8a 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -949,7 +949,7 @@ out1:
i = 4;
out:
while (i--)
- kfree(qe_devs[i]);
+ free_netdev(qe_devs[i]);
return res;
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index c31dc44a6fd2..3ebedccf00b3 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7740,7 +7740,7 @@ err_out_iounmap:
iounmap((void *) tp->regs);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_free_res:
pci_release_regions(pdev);
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 5a45900a816e..c5b6999712fb 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -670,7 +670,7 @@ err_out_uninit:
pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
priv->dmaStorageDMA );
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_regions:
if (pdev)
pci_release_regions(pdev);
@@ -695,7 +695,7 @@ static void TLan_Eisa_Cleanup(void)
release_region( dev->base_addr, 0x10);
unregister_netdev( dev );
TLan_Eisa_Devices = priv->nextDevice;
- kfree( dev );
+ free_netdev( dev );
tlan_have_eisa--;
}
}
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index e83372b7adbb..f30b72218b30 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -2455,7 +2455,7 @@ error_out_remap:
error_out_regions:
pci_release_regions(pdev);
error_out_dev:
- kfree(dev);
+ free_netdev(dev);
error_out:
return err;
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index c247af6bf6ad..3059d04aaf0d 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -868,7 +868,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree (dev);
+ free_netdev (dev);
err_out:
return -ENODEV;
}
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 5aab67436cc7..380bb830d738 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -55,14 +55,13 @@
#include <asm/dma.h>
#include <asm/uaccess.h>
-static const char devname[] = "dlci";
static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";
-static struct net_device *open_dev[CONFIG_DLCI_COUNT];
-
+static LIST_HEAD(dlci_devs);
+static spinlock_t dlci_dev_lock = SPIN_LOCK_UNLOCKED;
static char *basename[16];
-int dlci_init(struct net_device *dev);
+static void dlci_setup(struct net_device *);
/* allow FRAD's to register their name as a valid FRAD */
int register_frad(const char *name)
@@ -115,6 +114,7 @@ int unregister_frad(const char *name)
return(0);
}
+EXPORT_SYMBOL(unregister_frad);
/*
* these encapsulate the RFC 1490 requirements as well as
@@ -168,6 +168,14 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
int process, header;
dlp = dev->priv;
+ if (!pskb_may_pull(skb, sizeof(*hdr))) {
+ printk(KERN_NOTICE "%s: invalid data no header\n",
+ dev->name);
+ dlp->stats.rx_errors++;
+ kfree_skb(skb);
+ return;
+ }
+
hdr = (struct frhdr *) skb->data;
process = 0;
header = 0;
@@ -277,7 +285,7 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
return(ret);
}
-int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
+static int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
{
struct dlci_conf config;
struct dlci_local *dlp;
@@ -311,7 +319,7 @@ int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
return(0);
}
-int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct dlci_local *dlp;
@@ -401,21 +409,23 @@ static struct net_device_stats *dlci_get_stats(struct net_device *dev)
return(&dlp->stats);
}
-int dlci_add(struct dlci_add *dlci)
+static int dlci_add(struct dlci_add *dlci)
{
- struct net_device *master, *slave;
+ struct net_device *master, *slave;
struct dlci_local *dlp;
struct frad_local *flp;
int err, i;
- char buf[10];
+
/* validate slave device */
- slave = __dev_get_by_name(dlci->devname);
+ slave = dev_get_by_name(dlci->devname);
if (!slave)
return(-ENODEV);
- if (slave->type != ARPHRD_FRAD)
+ if (slave->type != ARPHRD_FRAD) {
+ dev_put(slave);
return(-EINVAL);
+ }
/* check for registration */
for (i=0;i<sizeof(basename) / sizeof(char *); i++)
@@ -424,33 +434,22 @@ int dlci_add(struct dlci_add *dlci)
(strlen(dlci->devname) > strlen(basename[i])))
break;
- if (i == sizeof(basename) / sizeof(char *))
+ if (i == sizeof(basename) / sizeof(char *)) {
+ dev_put(slave);
return(-EINVAL);
-
- /* check for too many open devices : should this be dynamic ? */
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (!open_dev[i])
- break;
-
- if (i == CONFIG_DLCI_COUNT)
- return(-ENOSPC); /* #### Alan: Comments on this?? */
+ }
/* create device name */
- sprintf(buf, "%s%02i", devname, i);
-
- master = kmalloc(sizeof(*master), GFP_KERNEL);
- if (!master)
+ master = alloc_netdev( sizeof(struct dlci_local), "dlci%d",
+ dlci_setup);
+ if (!master) {
+ dev_put(slave);
return(-ENOMEM);
-
- memset(master, 0, sizeof(*master));
-
- strcpy(master->name, buf);
- master->init = dlci_init;
- master->flags = 0;
+ }
err = register_netdev(master);
- if (err < 0)
- {
+ if (err < 0) {
+ dev_put(slave);
kfree(master);
return(err);
}
@@ -459,64 +458,65 @@ int dlci_add(struct dlci_add *dlci)
dlp = (struct dlci_local *) master->priv;
dlp->slave = slave;
+ dlp->master = master;
flp = slave->priv;
err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
if (err < 0)
{
unregister_netdev(master);
- kfree(master->priv);
- kfree(master);
+ dev_put(slave);
+ free_netdev(master);
return(err);
}
- strcpy(dlci->devname, buf);
- open_dev[i] = master;
- MOD_INC_USE_COUNT;
+ strcpy(dlci->devname, master->name);
+
+ spin_lock_bh(&dlci_dev_lock);
+ list_add(&dlp->list, &dlci_devs);
+ spin_unlock_bh(&dlci_dev_lock);
+
return(0);
}
-int dlci_del(struct dlci_add *dlci)
+static int dlci_del(struct dlci_add *dlci)
{
struct dlci_local *dlp;
struct frad_local *flp;
- struct net_device *master, *slave;
- int i, err;
+ struct net_device *master, *slave;
+ int err;
/* validate slave device */
master = __dev_get_by_name(dlci->devname);
if (!master)
return(-ENODEV);
- if (netif_running(master))
+ if (netif_running(master)) {
return(-EBUSY);
+ }
dlp = master->priv;
slave = dlp->slave;
flp = slave->priv;
err = (*flp->deassoc)(slave, master);
- if (err)
+ if (err)
return(err);
- unregister_netdev(master);
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (master == open_dev[i])
- break;
+ spin_lock_bh(&dlci_dev_lock);
+ list_del(&dlp->list);
+ spin_unlock_bh(&dlci_dev_lock);
- if (i<CONFIG_DLCI_COUNT)
- open_dev[i] = NULL;
+ unregister_netdev(master);
- kfree(master->priv);
+ dev_put(slave);
free_netdev(master);
- MOD_DEC_USE_COUNT;
-
return(0);
}
-int dlci_ioctl(unsigned int cmd, void *arg)
+static int dlci_ioctl(unsigned int cmd, void *arg)
{
struct dlci_add add;
int err;
@@ -548,16 +548,9 @@ int dlci_ioctl(unsigned int cmd, void *arg)
return(err);
}
-int dlci_init(struct net_device *dev)
+static void dlci_setup(struct net_device *dev)
{
- struct dlci_local *dlp;
-
- dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL);
- if (!dev->priv)
- return(-ENOMEM);
-
- memset(dev->priv, 0, sizeof(struct dlci_local));
- dlp = dev->priv;
+ struct dlci_local *dlp = dev->priv;
dev->flags = 0;
dev->open = dlci_open;
@@ -573,9 +566,7 @@ int dlci_init(struct net_device *dev)
dev->type = ARPHRD_DLCI;
dev->hard_header_len = sizeof(struct frhdr);
dev->addr_len = sizeof(short);
- memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
- return(0);
}
int __init init_dlci(void)
@@ -584,9 +575,6 @@ int __init init_dlci(void)
dlci_ioctl_set(dlci_ioctl);
printk("%s.\n", version);
-
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- open_dev[i] = NULL;
for(i=0;i<sizeof(basename) / sizeof(char *);i++)
basename[i] = NULL;
@@ -596,7 +584,16 @@ int __init init_dlci(void)
void __exit dlci_exit(void)
{
+ struct dlci_local *dlp, *nxt;
+
dlci_ioctl_set(NULL);
+
+ list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) {
+ unregister_netdev(dlp->master);
+ dev_put(dlp->slave);
+ free_netdev(dlp->master);
+ }
+
}
module_init(init_dlci);
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 349400d4d95a..81b2f271036c 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -140,6 +140,7 @@ static void change_level( struct net_device * );
static void timeout_change_level( struct net_device * );
static u32 calc_crc32( u32, u8 *, u32 );
static struct sk_buff * get_rx_buf( struct net_device * );
+static int sbni_init( struct net_device * );
#ifdef CONFIG_SBNI_MULTILINE
static int enslave( struct net_device *, struct net_device * );
@@ -205,23 +206,44 @@ sbni_isa_probe( struct net_device *dev )
}
}
-
-int __init
-sbni_probe( struct net_device *dev )
+static void __init sbni_devsetup(struct net_device *dev)
{
- int i;
+ ether_setup( dev );
+ dev->init = &sbni_init;
+ dev->open = &sbni_open;
+ dev->stop = &sbni_close;
+ dev->hard_start_xmit = &sbni_start_xmit;
+ dev->get_stats = &sbni_get_stats;
+ dev->set_multicast_list = &set_multicast_list;
+ dev->do_ioctl = &sbni_ioctl;
+
+ SET_MODULE_OWNER( dev );
+}
+int __init sbni_probe(void)
+{
+ struct net_device *dev;
static unsigned version_printed __initdata = 0;
+
if( version_printed++ == 0 )
printk( KERN_INFO "%s", version );
- if( !dev ) { /* simple sanity check */
- printk( KERN_ERR "sbni: NULL device!\n" );
- return -ENODEV;
- }
+ dev = alloc_netdev(sizeof(struct net_local), "sbni%d", sbni_devsetup);
+ if (!dev)
+ return -ENOMEM;
- SET_MODULE_OWNER( dev );
+ netdev_boot_setup_check(dev);
+
+ if (register_netdev(dev)) {
+ kfree(dev);
+ return -ENODEV;
+ }
+ return 0;
+}
+static int __init sbni_init(struct net_device *dev)
+{
+ int i;
if( dev->base_addr )
return sbni_isa_probe( dev );
/* otherwise we have to perform search our adapter */
@@ -338,7 +360,7 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq )
dev->base_addr = ioaddr;
/* Allocate dev->priv and fill in sbni-specific dev fields. */
- nl = (struct net_local *) kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ nl = dev->priv;
if( !nl ) {
printk( KERN_ERR "%s: unable to get memory!\n", dev->name );
release_region( ioaddr, SBNI_IO_EXTENT );
@@ -389,14 +411,6 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq )
nl->link = NULL;
#endif
- dev->open = &sbni_open;
- dev->stop = &sbni_close;
- dev->hard_start_xmit = &sbni_start_xmit;
- dev->get_stats = &sbni_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &sbni_ioctl;
- ether_setup( dev );
-
sbni_cards[ num++ ] = dev;
return dev;
}
@@ -1478,15 +1492,15 @@ init_module( void )
struct net_device *dev;
while( num < SBNI_MAX_NUM_CARDS ) {
- if( !(dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) ){
+ dev = alloc_netdev(sizeof(struct net_local),
+ "sbni%d", sbni_devsetup);
+ if( !dev) {
printk( KERN_ERR "sbni: unable to allocate device!\n" );
return -ENOMEM;
}
- memset( dev, 0, sizeof(struct net_device) );
sprintf( dev->name, "sbni%d", num );
- dev->init = sbni_probe;
if( register_netdev( dev ) ) {
kfree( dev );
break;
@@ -1506,7 +1520,6 @@ cleanup_module( void )
if( (dev = sbni_cards[ num ]) != NULL ) {
unregister_netdev( dev );
release_region( dev->base_addr, SBNI_IO_EXTENT );
- kfree( dev->priv );
free_netdev( dev );
}
}
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 8079d8b5ddee..c91e59da2ed9 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -71,6 +71,8 @@ static unsigned int valid_mem[] __initdata = {
0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
+static spinlock_t sdla_lock = SPIN_LOCK_UNLOCKED;
+
/*********************************************************
*
* these are the core routines that access the card itself
@@ -79,10 +81,10 @@ static unsigned int valid_mem[] __initdata = {
#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
-static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
+static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
- unsigned long flags;
- char *temp, *base;
+ char *temp;
+ const void *base;
int offset, bytes;
temp = buf;
@@ -90,13 +92,10 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
- base = (void *) (dev->mem_start + offset);
+ base = (const void *) (dev->mem_start + offset);
- save_flags(flags);
- cli();
SDLA_WINDOW(dev, addr);
memcpy(temp, base, bytes);
- restore_flags(flags);
addr += bytes;
temp += bytes;
@@ -104,10 +103,19 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
}
}
-static void sdla_write(struct net_device *dev, int addr, void *buf, short len)
+static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
unsigned long flags;
- char *temp, *base;
+ spin_lock_irqsave(&sdla_lock, flags);
+ __sdla_read(dev, addr, buf, len);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+}
+
+static void __sdla_write(struct net_device *dev, int addr,
+ const void *buf, short len)
+{
+ const char *temp;
+ void *base;
int offset, bytes;
temp = buf;
@@ -116,17 +124,27 @@ static void sdla_write(struct net_device *dev, int addr, void *buf, short len)
offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
base = (void *) (dev->mem_start + offset);
- save_flags(flags);
- cli();
+
SDLA_WINDOW(dev, addr);
memcpy(base, temp, bytes);
- restore_flags(flags);
+
addr += bytes;
temp += bytes;
len -= bytes;
}
}
+static void sdla_write(struct net_device *dev, int addr,
+ const void *buf, short len)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdla_lock, flags);
+ __sdla_write(dev, addr, buf, len);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+}
+
+
static void sdla_clear(struct net_device *dev)
{
unsigned long flags;
@@ -138,8 +156,7 @@ static void sdla_clear(struct net_device *dev)
bytes = SDLA_WINDOW_SIZE;
base = (void *) dev->mem_start;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
while(len)
{
SDLA_WINDOW(dev, addr);
@@ -148,7 +165,8 @@ static void sdla_clear(struct net_device *dev)
addr += bytes;
len -= bytes;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+
}
static char sdla_byte(struct net_device *dev, int addr)
@@ -158,11 +176,10 @@ static char sdla_byte(struct net_device *dev, int addr)
temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
SDLA_WINDOW(dev, addr);
byte = *temp;
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
return(byte);
}
@@ -414,7 +431,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
struct frad_local *flp;
struct sdla_cmd *cmd_buf;
unsigned long pflags;
- int jiffs, ret, waiting, len;
+ unsigned long jiffs;
+ int ret, waiting, len;
long window;
flp = dev->priv;
@@ -423,8 +441,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
ret = 0;
len = 0;
jiffs = jiffies + HZ; /* 1 second is plenty */
- save_flags(pflags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
cmd_buf->cmd = cmd;
cmd_buf->dlci = dlci;
@@ -436,7 +454,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
cmd_buf->length = inlen;
cmd_buf->opp_flag = 1;
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
waiting = 1;
len = 0;
@@ -444,18 +462,17 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
{
if (waiting++ % 3)
{
- save_flags(pflags);
- cli();
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
waiting = ((volatile int)(cmd_buf->opp_flag));
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
}
}
if (!waiting)
{
- save_flags(pflags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
ret = cmd_buf->retval;
len = cmd_buf->length;
@@ -471,7 +488,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
if (ret)
memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
}
else
ret = SDLA_RET_TIMEOUT;
@@ -555,7 +572,6 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
if (i == CONFIG_DLCI_MAX)
return(-EMLINK); /* #### Alan: Comments on this ?? */
- MOD_INC_USE_COUNT;
flp->master[i] = master;
flp->dlci[i] = -*(short *)(master->dev_addr);
@@ -588,7 +604,6 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
flp->master[i] = NULL;
flp->dlci[i] = 0;
- MOD_DEC_USE_COUNT;
if (netif_running(slave)) {
if (flp->config.station == FRAD_STATION_CPE)
@@ -688,14 +703,14 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
if (ret == SDLA_RET_OK)
{
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, flags);
SDLA_WINDOW(dev, addr);
pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
- sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
- SDLA_WINDOW(dev, addr);
+ __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+ SDLA_WINDOW(dev, addr);
pbuf->opp_flag = 1;
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
}
break;
}
@@ -753,8 +768,7 @@ static void sdla_receive(struct net_device *dev)
pbufi = NULL;
pbuf = NULL;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
switch (flp->type)
{
@@ -821,7 +835,7 @@ static void sdla_receive(struct net_device *dev)
case SDLA_S502A:
case SDLA_S502E:
if (success)
- sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
+ __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
cmd->opp_flag = 0;
@@ -834,9 +848,9 @@ static void sdla_receive(struct net_device *dev)
split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
len2 = len - split;
- sdla_read(dev, addr, skb_put(skb, len2), len2);
+ __sdla_read(dev, addr, skb_put(skb, len2), len2);
if (split)
- sdla_read(dev, buf_base, skb_put(skb, split), split);
+ __sdla_read(dev, buf_base, skb_put(skb, split), split);
}
/* increment the buffer we're looking at */
@@ -853,7 +867,7 @@ static void sdla_receive(struct net_device *dev)
(*dlp->receive)(skb, master);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
}
static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
@@ -979,8 +993,6 @@ static int sdla_close(struct net_device *dev)
netif_stop_queue(dev);
- MOD_DEC_USE_COUNT;
-
return(0);
}
@@ -1082,8 +1094,6 @@ static int sdla_open(struct net_device *dev)
netif_start_queue(dev);
- MOD_INC_USE_COUNT;
-
return(0);
}
@@ -1614,19 +1624,30 @@ static struct net_device_stats *sdla_stats(struct net_device *dev)
return(&flp->stats);
}
-int __init sdla_init(struct net_device *dev)
+static void setup_sdla(struct net_device *dev)
{
+ dev->flags = 0;
+ dev->type = 0xFFFF;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->mtu = SDLA_MAX_MTU;
+}
+
+struct net_device * __init sdla_init(void)
+{
+ struct net_device *dev;
struct frad_local *flp;
+ int err = -ENOMEM;
- /* allocate the private data structure */
- flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
- if (!flp)
- return(-ENOMEM);
+ dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
+ if (!dev)
+ goto out;
- memset(flp, 0, sizeof(struct frad_local));
- dev->priv = flp;
+ SET_MODULE_OWNER(dev);
+ netdev_boot_setup_check(dev);
+
+ flp = dev->priv;
- dev->flags = 0;
dev->open = sdla_open;
dev->stop = sdla_close;
dev->do_ioctl = sdla_ioctl;
@@ -1635,12 +1656,6 @@ int __init sdla_init(struct net_device *dev)
dev->hard_start_xmit = sdla_transmit;
dev->change_mtu = sdla_change_mtu;
- dev->type = 0xFFFF;
- dev->hard_header_len = 0;
- dev->addr_len = 0;
- dev->mtu = SDLA_MAX_MTU;
- SET_MODULE_OWNER(dev);
-
flp->activate = sdla_activate;
flp->deactivate = sdla_deactivate;
flp->assoc = sdla_assoc;
@@ -1652,7 +1667,14 @@ int __init sdla_init(struct net_device *dev)
flp->timer.data = (unsigned long) dev;
flp->timer.function = sdla_poll;
- return(0);
+ err = register_netdev(dev);
+ if (err)
+ goto out1;
+ return dev;
+out1:
+ kfree(dev);
+out:
+ return ERR_PTR(err);
}
int __init sdla_c_setup(void)
@@ -1663,10 +1685,7 @@ int __init sdla_c_setup(void)
}
#ifdef MODULE
-static struct net_device sdla0 = {
- .name = "sdla0",
- .init = sdla_init
-};
+static struct net_device *sdla0;
#endif /* MODULE */
static int __init init_sdla(void)
@@ -1675,7 +1694,9 @@ static int __init init_sdla(void)
sdla_c_setup();
#ifdef MODULE
- result = register_netdev(&sdla0);
+ sdla0 = sdla_init();
+ if (IS_ERR(sdla0))
+ result = PTR_ERR(sdla0);
#endif
return result;
}
@@ -1683,11 +1704,10 @@ static int __init init_sdla(void)
static void __exit exit_sdla(void)
{
#ifdef MODULE
- unregister_netdev(&sdla0);
- if (sdla0.priv)
- kfree(sdla0.priv);
- if (sdla0.irq)
- free_irq(sdla0.irq, &sdla0);
+ unregister_netdev(sdla0);
+ if (sdla0->irq)
+ free_irq(sdla0->irq, sdla0);
+ free_netdev(sdla0);
#endif
}
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 8a3328687d1f..c22ca46b0d81 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -577,7 +577,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree (dev);
+ free_netdev (dev);
return -ENODEV;
}