All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] (12/12) Probe2 -- 82596
@ 2003-10-14 22:34 Stephen Hemminger
  0 siblings, 0 replies; only message in thread
From: Stephen Hemminger @ 2003-10-14 22:34 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev

Originally by Al Viro (NE23-82596)
	* switched 82596 to dynamic allocation
	* 82596: fixed resource leaks on failure exits
Updated to apply agains jgarzik/net-drivers-2.5-exp

diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c
--- a/drivers/net/82596.c	Tue Oct 14 14:46:31 2003
+++ b/drivers/net/82596.c	Tue Oct 14 14:46:31 2003
@@ -1129,21 +1129,40 @@
 	printk(" %02X%02X, %s\n", add[12], add[13], str);
 }
 
-int __init i82596_probe(struct net_device *dev)
+static int io = 0x300;
+static int irq = 10;
+
+struct net_device * __init i82596_probe(int unit)
 {
+	struct net_device *dev;
 	int i;
 	struct i596_private *lp;
 	char eth_addr[8];
 	static int probed;
+	int err;
 
 	if (probed)
-		return -ENODEV;
+		return ERR_PTR(-ENODEV);
 	probed++;
+
+	dev = alloc_etherdev(0);
+	if (!dev)
+		return ERR_PTR(-ENOMEM);
+
+	if (unit >= 0) {
+		sprintf(dev->name, "eth%d", unit);
+		netdev_boot_setup_check(dev);
+	} else {
+		dev->base_addr = io;
+		dev->irq = irq;
+	}
+
 #ifdef ENABLE_MVME16x_NET
 	if (MACH_IS_MVME16x) {
 		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
 			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
-			return -ENODEV;
+			err = -ENODEV;
+			goto out;
 		}
 		memcpy(eth_addr, (void *) 0xfffc1f2c, 6);	/* YUCK! Get addr from NOVRAM */
 		dev->base_addr = MVME_I596_BASE;
@@ -1174,7 +1193,8 @@
 
 		if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
 			printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
-			return -EBUSY;
+			err = -EBUSY;
+			goto out;
 		}
 
 		for (i = 0; i < 8; i++) {
@@ -1190,8 +1210,8 @@
 
 		if ((checksum % 0x100) || 
 		    (memcmp(eth_addr, "\x00\x00\x49", 3) != 0)) {
-			release_region(ioaddr, I596_TOTAL_SIZE);
-			return -ENODEV;
+			err = -ENODEV;
+			goto out1;
 		}
 
 		dev->base_addr = ioaddr;
@@ -1200,13 +1220,10 @@
 #endif
 	dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
 	if (!dev->mem_start) {
-#ifdef ENABLE_APRICOT
-		release_region(dev->base_addr, I596_TOTAL_SIZE);
-#endif
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out1;
 	}
 
-	ether_setup(dev);
 	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
 	for (i = 0; i < 6; i++)
@@ -1244,7 +1261,26 @@
 	lp->scb.rfd = I596_NULL;
 	lp->lock = SPIN_LOCK_UNLOCKED;
 
-	return 0;
+	err = register_netdev(dev);
+	if (err)
+		goto out2;
+	return dev;
+out2:
+#ifdef __mc68000__
+	/* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
+	 * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
+	 */
+	kernel_set_cachemode((void *)(dev->mem_start), 4096,
+			IOMAP_FULL_CACHING);
+#endif
+	free_page ((u32)(dev->mem_start));
+out1:
+#ifdef ENABLE_APRICOT
+	release_region(dev->base_addr, I596_TOTAL_SIZE);
+#endif
+out:
+	free_netdev(dev);
+	return ERR_PTR(err);
 }
 
 static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -1532,11 +1568,9 @@
 }
 
 #ifdef MODULE
-static struct net_device dev_82596 = { .init = i82596_probe };
+static struct net_device *dev_82596;
 
 #ifdef ENABLE_APRICOT
-static int io = 0x300;
-static int irq = 10;
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(irq, "Apricot IRQ number");
 #endif
@@ -1547,34 +1581,31 @@
 
 int init_module(void)
 {
-#ifdef ENABLE_APRICOT
-	dev_82596.base_addr = io;
-	dev_82596.irq = irq;
-#endif
 	if (debug >= 0)
 		i596_debug = debug;
-	if (register_netdev(&dev_82596) != 0)
-		return -EIO;
+	dev_82596 = i82596_probe(-1);
+	if (IS_ERR(dev_82596))
+		return PTR_ERR(dev_82596);
 	return 0;
 }
 
 void cleanup_module(void)
 {
-	unregister_netdev(&dev_82596);
+	unregister_netdev(dev_82596);
 #ifdef __mc68000__
 	/* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
 	 * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
 	 */
 
-	kernel_set_cachemode((void *)(dev_82596.mem_start), 4096,
+	kernel_set_cachemode((void *)(dev_82596->mem_start), 4096,
 			IOMAP_FULL_CACHING);
 #endif
-	free_page ((u32)(dev_82596.mem_start));
-	dev_82596.priv = NULL;
+	free_page ((u32)(dev_82596->mem_start));
 #ifdef ENABLE_APRICOT
 	/* If we don't do this, we can't re-insmod it later. */
-	release_region(dev_82596.base_addr, I596_TOTAL_SIZE);
+	release_region(dev_82596->base_addr, I596_TOTAL_SIZE);
 #endif
+	free_netdev(dev_82596);
 }
 
 #endif				/* MODULE */
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Tue Oct 14 14:46:31 2003
+++ b/drivers/net/Space.c	Tue Oct 14 14:46:31 2003
@@ -55,7 +55,7 @@
 extern int at1700_probe(struct net_device *);
 extern int fmv18x_probe(struct net_device *);
 extern int eth16i_probe(struct net_device *);
-extern int i82596_probe(struct net_device *);
+extern struct net_device *i82596_probe(int unit);
 extern int ewrk3_probe(struct net_device *);
 extern struct net_device *el1_probe(int unit);
 extern struct net_device *wavelan_probe(int unit);
@@ -259,13 +259,13 @@
 #ifdef CONFIG_EWRK3             /* DEC EtherWORKS 3 */
     	{ewrk3_probe, 0},
 #endif
-#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET)	/* Intel I82596 */
-	{i82596_probe, 0},
-#endif
 	{NULL, 0},
 };
 
 static struct devprobe2 isa_probes2[] __initdata = {
+#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET)	/* Intel I82596 */
+	{i82596_probe, 0},
+#endif
 #ifdef CONFIG_EL1		/* 3c501 */
 	{el1_probe, 0},
 #endif

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-10-14 22:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 22:34 [PATCH] (12/12) Probe2 -- 82596 Stephen Hemminger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.