[PATCH] (29/42) bagetlance

DORMANTno replies

From: Stephen Hemminger <hidden>
Date: 2003-11-13 00:45:08

NE54-bagetlance
	* switched bagetlance to dynamic allocation
	* bagetlance: embedded ->priv
	* bagetlance: fixed resource leaks on failure exits
	* bagetlance: fixed resource leaks on rmmod

diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Tue Nov 11 14:15:23 2003
+++ b/drivers/net/Space.c	Tue Nov 11 14:15:23 2003
@@ -82,7 +82,7 @@
 extern int pamsnet_probe(struct net_device *);
 extern struct net_device *cs89x0_probe(int unit);
 extern int hplance_probe(struct net_device *dev);
-extern int bagetlance_probe(struct net_device *);
+extern struct net_device *bagetlance_probe(int unit);
 extern int mvme147lance_probe(struct net_device *dev);
 extern struct net_device *tc515_probe(int unit);
 extern struct net_device *lance_probe(int unit);
@@ -339,6 +339,10 @@
 #ifdef CONFIG_MIPS_JAZZ_SONIC
 	{sonic_probe, 0},
 #endif
+	{NULL, 0},
+};
+
+static struct devprobe2 mips_probes2[] __initdata = {
 #ifdef CONFIG_BAGETLANCE        /* Lance-based Baget ethernet boards */
         {bagetlance_probe, 0},
 #endif
@@ -392,6 +396,7 @@
 	if (base_addr == 1)
 		return;
 
+	probe_list2(unit, mips_probes2, base_addr == 0) &&
 	probe_list2(unit, eisa_probes, base_addr == 0) &&
 	probe_list2(unit, mca_probes, base_addr == 0) &&
 	probe_list2(unit, isa_probes, base_addr == 0) &&
diff -Nru a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c
--- a/drivers/net/bagetlance.c	Tue Nov 11 14:15:23 2003
+++ b/drivers/net/bagetlance.c	Tue Nov 11 14:15:23 2003
@@ -465,30 +465,43 @@
 }
 
 
-int __init bagetlance_probe( struct net_device *dev )
-
-{	int i;
+struct net_device * __init bagetlance_probe(int unit)
+{
+	struct net_device *dev;
+	int i;
 	static int found;
-
-	SET_MODULE_OWNER(dev);
+	int err = -ENODEV;
 
 	if (found)
 		/* Assume there's only one board possible... That seems true, since
 		 * the Riebl/PAM board's address cannot be changed. */
-		return( -ENODEV );
+		return ERR_PTR(-ENODEV);
+
+	dev = alloc_etherdev(sizeof(struct lance_private));
+	if (!dev)
+		return ERR_PTR(-ENOMEM);
+
+	SET_MODULE_OWNER(dev);
 
 	for( i = 0; i < N_LANCE_ADDR; ++i ) {
 		if (lance_probe1( dev, &lance_addr_list[i] )) {
 			found = 1;
-			return( 0 );
+			break;
 		}
 	}
-
-	return( -ENODEV );
+	if (!found)
+		goto out;
+	err = register_netdev(dev);
+	if (err)
+		goto out1;
+	return dev;
+out1:
+	free_irq(dev->irq, dev);
+out:
+	free_netdev(dev);
+	return ERR_PTR(err);
 }
 
-
-
 /* Derived from hwreg_present() in vme/config.c: */
 
 static int __init addr_accessible( volatile void *regp, 
@@ -527,6 +540,7 @@
 	if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
 
 	if ((unsigned long)memaddr >= KSEG2) {
+			/* FIXME: do we need to undo that on cleanup paths? */
 			extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
 			if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
 					printk("bagetlance: unable map lance memory\n");
@@ -580,12 +594,6 @@
 	return( 0 );
 
   probe_ok:
-	init_etherdev( dev, sizeof(struct lance_private) );
-	if (!dev->priv) {
-		dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
-		if (!dev->priv)
-			return 0;
-	}
 	lp = (struct lance_private *)dev->priv;
 	MEM = (struct lance_memory *)memaddr;
 	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
@@ -617,8 +625,9 @@
 	if (lp->cardtype == PAM_CARD ||
 		memaddr == (unsigned short *)0xffe00000) {
 		/* PAMs card and Riebl on ST use level 5 autovector */
-		request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
-		            "PAM/Riebl-ST Ethernet", dev);
+		if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
+		            "PAM/Riebl-ST Ethernet", dev))
+			goto probe_fail;
 		dev->irq = (unsigned short)BAGET_LANCE_IRQ;
 	}
 	else {
@@ -629,10 +638,11 @@
 		unsigned long irq = BAGET_LANCE_IRQ; 
 		if (!irq) {
 			printk( "Lance: request for VME interrupt failed\n" );
-			return( 0 );
+			goto probe_fail;
 		}
-		request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
-		            "Riebl-VME Ethernet", dev);
+		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
+		            "Riebl-VME Ethernet", dev))
+			goto probe_fail;
 		dev->irq = irq;
 	}
 
@@ -1331,26 +1341,21 @@
 
 
 #ifdef MODULE
-static struct net_device bagetlance_dev;
+static struct net_device *bagetlance_dev;
 
 int init_module(void)
-
-{	int err;
-
-	bagetlance_dev.init = bagetlance_probe;
-	if ((err = register_netdev( &bagetlance_dev ))) {
-		if (err == -EIO)  {
-			printk( "No Vme Lance board found. Module not loaded.\n");
-		}
-		return( err );
-	}
-	return( 0 );
+{
+	bagetlance_dev = bagetlance_probe(-1);
+	if (IS_ERR(bagetlance_dev))
+		return PTR_ERR(bagetlance_dev);
+	return 0;
 }
 
 void cleanup_module(void)
-
 {
-	unregister_netdev( &bagetlance_dev );
+	unregister_netdev(bagetlance_dev);
+	free_irq(bagetlance_dev->irq, bagetlance_dev);
+	free_netdev(bagetlance_dev);
 }
 
 #endif /* MODULE */
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help