DORMANTno replies

[PATCH] (08/12) Probe2 -- 3c507

From: Stephen Hemminger <hidden>
Date: 2003-10-14 22:34:10

Originally by Al Viro (NE19-3c507)
	* switched 3c507 to dynamic allocation
	* 3c507: embedded ->priv
	* 3c507: fixed clobbering on autoprobe
	* NB: 3c507.c buggers port 0x100 without claiming it.  Most likely it
	  should be doing request_region() there.
Updated to apply agains jgarzik/net-drivers-2.5-exp

diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c
--- a/drivers/net/3c507.c	Tue Oct 14 14:27:21 2003
+++ b/drivers/net/3c507.c	Tue Oct 14 14:27:21 2003
@@ -74,10 +74,6 @@
 #define debug net_debug
 
 
-/* A zero-terminated list of common I/O addresses to be probed. */
-static unsigned int netcard_portlist[] __initdata =
-	{ 0x300, 0x320, 0x340, 0x280, 0};
-
 /*
   			Details of the i82586.
 
@@ -286,8 +282,6 @@
 
 /* Index to functions, as function prototypes. */
 
-extern int el16_probe(struct net_device *dev);	/* Called from Space.c */
-
 static int	el16_probe1(struct net_device *dev, int ioaddr);
 static int	el16_open(struct net_device *dev);
 static int	el16_send_packet(struct sk_buff *skb, struct net_device *dev);
@@ -301,6 +295,10 @@
 static void init_82586_mem(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
+static int io = 0x300;
+static int irq;
+static int mem_start;
+
 

 /* Check for a network adaptor of this type, and return '0' iff one exists.
 	If dev->base_addr == 0, probe all likely locations.
@@ -309,23 +307,50 @@
 	device and return success.
 	*/
 
-int __init el16_probe(struct net_device *dev)
+struct net_device * __init el16_probe(int unit)
 {
-	int base_addr = dev->base_addr;
-	int i;
+	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+	static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
+	unsigned *port;
+	int err = -ENODEV;
+
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	if (unit >= 0) {
+		sprintf(dev->name, "eth%d", unit);
+		netdev_boot_setup_check(dev);
+		io = dev->base_addr;
+		irq = dev->irq;
+		mem_start = dev->mem_start & 15;
+	}
 
 	SET_MODULE_OWNER(dev);
 
-	if (base_addr > 0x1ff)	/* Check a single specified location. */
-		return el16_probe1(dev, base_addr);
-	else if (base_addr != 0)
-		return -ENXIO;		/* Don't probe at all. */
-
-	for (i = 0; netcard_portlist[i]; i++)
-		if (el16_probe1(dev, netcard_portlist[i]) == 0)
-			return 0;
+	if (io > 0x1ff) 	/* Check a single specified location. */
+		err = el16_probe1(dev, io);
+	else if (io != 0)
+		err = -ENXIO;		/* Don't probe at all. */
+	else {
+			for (port = ports; *port; port++) {
+					err = el16_probe1(dev, io);
+					if (!err)
+						break;
+			}
+	}
 
-	return -ENODEV;
+	if (err)
+		goto out;
+	err = register_netdev(dev);
+	if (err)
+		goto out1;
+	return dev;
+out1:
+	free_irq(dev->irq, dev);
+	release_region(dev->base_addr, EL16_IO_EXTENT);
+out:
+	free_netdev(dev);
+	return ERR_PTR(err);
 }
 
 static int __init el16_probe1(struct net_device *dev, int ioaddr)
@@ -383,8 +408,8 @@
 		printk(" %02x", dev->dev_addr[i]);
 	}
 
-	if ((dev->mem_start & 0xf) > 0)
-		net_debug = dev->mem_start & 7;
+	if (mem_start)
+		net_debug = mem_start & 7;
 
 #ifdef MEM_BASE
 	dev->mem_start = MEM_BASE;
@@ -416,27 +441,18 @@
 	if (net_debug)
 		printk(version);
 
-	/* Initialize the device structure. */
-	lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-	if (dev->priv == NULL) {
-		retval = -ENOMEM;
-		goto out;
-	}
-	memset(dev->priv, 0, sizeof(struct net_local));
+	lp = dev->priv;
+ 	memset(lp, 0, sizeof(*lp));
 	spin_lock_init(&lp->lock);
 
-	dev->open		= el16_open;
-	dev->stop		= el16_close;
+ 	dev->open = el16_open;
+ 	dev->stop = el16_close;
 	dev->hard_start_xmit = el16_send_packet;
 	dev->get_stats	= el16_get_stats;
 	dev->tx_timeout = el16_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->ethtool_ops = &netdev_ethtool_ops;
-
-	ether_setup(dev);	/* Generic ethernet behaviour */
-
-	dev->flags&=~IFF_MULTICAST;	/* Multicast doesn't work */
-
+ 	dev->flags &= ~IFF_MULTICAST;	/* Multicast doesn't work */
 	return 0;
 out:
 	release_region(ioaddr, EL16_IO_EXTENT);
@@ -899,9 +915,7 @@
 };
 
 #ifdef MODULE
-static struct net_device dev_3c507;
-static int io = 0x300;
-static int irq;
+static struct net_device *dev_3c507;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
@@ -911,26 +925,18 @@
 {
 	if (io == 0)
 		printk("3c507: You should not use auto-probing with insmod!\n");
-	dev_3c507.base_addr = io;
-	dev_3c507.irq       = irq;
-	dev_3c507.init	    = el16_probe;
-	if (register_netdev(&dev_3c507) != 0) {
-		printk("3c507: register_netdev() returned non-zero.\n");
-		return -EIO;
-	}
-	return 0;
+	dev_3c507 = el16_probe(-1);
+	return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
 }
 
 void
 cleanup_module(void)
 {
-	unregister_netdev(&dev_3c507);
-	kfree(dev_3c507.priv);
-	dev_3c507.priv = NULL;
-
-	/* If we don't do this, we can't re-insmod it later. */
-	free_irq(dev_3c507.irq, &dev_3c507);
-	release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
+	struct net_device *dev = dev_3c507;
+	unregister_netdev(dev);
+	free_irq(dev->irq, dev);
+	release_region(dev->base_addr, EL16_IO_EXTENT);
+	free_netdev(dev);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Tue Oct 14 14:27:21 2003
+++ b/drivers/net/Space.c	Tue Oct 14 14:27:21 2003
@@ -60,7 +60,7 @@
 extern int el1_probe(struct net_device *);
 extern int wavelan_probe(struct net_device *);
 extern int arlan_probe(struct net_device *);
-extern int el16_probe(struct net_device *);
+extern struct net_device *el16_probe(int unit);
 extern int elmc_probe(struct net_device *);
 extern int skmca_probe(struct net_device *);
 extern struct net_device *elplus_probe(int unit);
@@ -271,13 +271,13 @@
 #ifdef CONFIG_ARLAN		/* Aironet */
 	{arlan_probe, 0},
 #endif
-#ifdef CONFIG_EL16		/* 3c507 */
-	{el16_probe, 0},
-#endif
 	{NULL, 0},
 };
 
 static struct devprobe2 isa_probes2[] __initdata = {
+#ifdef CONFIG_EL16		/* 3c507 */
+	{el16_probe, 0},
+#endif
 #ifdef CONFIG_ELPLUS		/* 3c505 */
 	{elplus_probe, 0},
 #endif
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help