patch-2.4.0-test2 linux/drivers/net/a2065.c

Next file: linux/drivers/net/ac3200.c
Previous file: linux/drivers/net/Space.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/drivers/net/a2065.c linux/drivers/net/a2065.c
@@ -132,8 +132,14 @@
 	int burst_sizes;	      /* ledma SBus burst sizes */
 #endif
 	struct timer_list         multicast_timer;
+	struct net_device *dev;		/* Backpointer */
+	struct lance_private *next_module;
 };
 
+#ifdef MODULE
+static struct lance_private *root_a2065_dev = NULL;
+#endif
+
 #define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
 			lp->tx_old+lp->tx_ring_mod_mask-lp->tx_new:\
 			lp->tx_old - lp->tx_new-1)
@@ -714,18 +720,14 @@
 
 static int __init a2065_probe(void)
 {
-	struct net_device *dev = NULL;
-	static int called = 0;
 	struct zorro_dev *z = NULL;
-
-	if (called)
-		return -ENODEV;
-	called++;
+	struct net_device *dev;
+	struct lance_private *priv;
+	int res = -ENODEV;
 
 	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
-		unsigned long board, base_addr, ram_start;
+		unsigned long board, base_addr, mem_start;
 		int is_cbm;
-		struct lance_private *priv;
 
 		if (z->id == ZORRO_PROD_CBM_A2065_1 ||
 		    z->id == ZORRO_PROD_CBM_A2065_2)
@@ -737,12 +739,12 @@
 
 		board = z->resource.start;
 		base_addr = board+A2065_LANCE;
-		ram_start = board+A2065_RAM;
+		mem_start = board+A2065_RAM;
 
 		if (!request_mem_region(base_addr, sizeof(struct lance_regs),
 					"Am7990"))
 			continue;
-		if (!request_mem_region(ram_start, A2065_RAM_SIZE, "RAM")) {
+		if (!request_mem_region(mem_start, A2065_RAM_SIZE, "RAM")) {
 			release_mem_region(base_addr,
 					   sizeof(struct lance_regs));
 			continue;
@@ -754,18 +756,18 @@
 		if (dev == NULL) {
 			release_mem_region(base_addr,
 					   sizeof(struct lance_regs));
-			release_mem_region(ram_start, A2065_RAM_SIZE);
+			release_mem_region(mem_start, A2065_RAM_SIZE);
 			return -ENOMEM;
 		}
 		priv = (struct lance_private *)dev->priv;
 		memset(priv, 0, sizeof(struct lance_private));
 
+		priv->dev = dev;
+		dev->dev_addr[0] = 0x00;
 		if (is_cbm) {				/* Commodore */
-			dev->dev_addr[0] = 0x00;
 			dev->dev_addr[1] = 0x80;
 			dev->dev_addr[2] = 0x10;
 		} else {				/* Ameristar */
-			dev->dev_addr[0] = 0x00;
 			dev->dev_addr[1] = 0x00;
 			dev->dev_addr[2] = 0x9f;
 		}
@@ -778,7 +780,7 @@
 		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 
 		dev->base_addr = ZTWO_VADDR(base_addr);
-		dev->mem_start = ZTWO_VADDR(ram_start);
+		dev->mem_start = ZTWO_VADDR(mem_start);
 		dev->mem_end = dev->mem_start+A2065_RAM_SIZE;
 
 		priv->ll = (volatile struct lance_regs *)dev->base_addr;
@@ -801,28 +803,38 @@
 		dev->set_multicast_list = &lance_set_multicast;
 		dev->dma = 0;
 
+#ifdef MODULE
+		priv->next_module = root_a2065_dev;
+		root_a2065_dev = priv;
+#endif
 		ether_setup(dev);
 		init_timer(&priv->multicast_timer);
 		priv->multicast_timer.data = (unsigned long) dev;
 		priv->multicast_timer.function =
 			(void (*)(unsigned long)) &lance_set_multicast;
 
-		return(0);
+		res = 0;
 	}
-	return(-ENODEV);
+	return res;
 }
 
 
 static void __exit a2065_cleanup(void)
 {
 #ifdef MODULE
-	struct lance_private *priv = (struct lance_private *)a2065_dev.priv;
+	struct lance_private *next;
+	struct net_device *dev;
 
-	unregister_netdev(&a2065_dev);
-	release_mem_region(ZTWO_PADDR(a2065_dev.base_addr),
-			   sizeof(struct lance_regs));
-	release_mem_region(ZTWO_PADDR(a2065_dev.mem_start), A2065_RAM_SIZE);
-	kfree(priv);
+	while (root_a2065_dev) {
+		next = root_a2065_dev->next_module;
+		dev = root_a2065_dev->dev;
+		unregister_netdev(dev);
+		release_mem_region(ZTWO_PADDR(dev->base_addr),
+				   sizeof(struct lance_regs));
+		release_mem_region(ZTWO_PADDR(dev->mem_start), A2065_RAM_SIZE);
+		kfree(dev);
+		root_a2065_dev = next;
+	}
 #endif
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)