patch-2.1.105 linux/drivers/net/wd.c

Next file: linux/drivers/scsi/NCR5380.c
Previous file: linux/drivers/net/smc-ultra32.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.104/linux/drivers/net/wd.c linux/drivers/net/wd.c
@@ -56,7 +56,7 @@
 						  struct sk_buff *skb, int ring_offset);
 static void wd_block_output(struct device *dev, int count,
 							const unsigned char *buf, int start_page);
-static int wd_close_card(struct device *dev);
+static int wd_close(struct device *dev);
 
 
 #define WD_START_PG		0x00	/* First page of TX buffer */
@@ -124,6 +124,10 @@
 		|| (checksum & 0xff) != 0xFF)
 		return ENODEV;
 
+	/* Looks like we have a card. Make sure 8390 support is available. */
+        if (load_8390_module("wd.c"))
+                return -ENOSYS;
+
 	/* We should have a "dev" from Space.c or the static module table. */
 	if (dev == NULL) {
 		printk("wd.c: Passed a NULL device.\n");
@@ -140,7 +144,7 @@
 	if (ei_debug  &&  version_printed++ == 0)
 		printk(version);
 
-	printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
+	printk("%s: WD80x3 at %#3x,", dev->name, ioaddr);
 	for (i = 0; i < 6; i++)
 		printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
 
@@ -252,20 +256,21 @@
 	} else if (dev->irq == 2)		/* Fixup bogosity: IRQ2 is really IRQ9 */
 		dev->irq = 9;
 
+	/* Allocate dev->priv and fill in 8390 specific dev fields. */
+	if (ethdev_init(dev)) {
+		printk (" unable to get memory for dev->priv.\n");
+		return -ENOMEM;
+	}
+
 	/* Snarf the interrupt now.  There's no point in waiting since we cannot
 	   share and the board will usually be enabled. */
 	if (request_irq(dev->irq, ei_interrupt, 0, model_name, dev)) {
 		printk (" unable to get IRQ %d.\n", dev->irq);
+		kfree(dev->priv);
+		dev->priv = NULL;
 		return EAGAIN;
 	}
 
-	/* Allocate dev->priv and fill in 8390 specific dev fields. */
-	if (ethdev_init(dev)) {
-		printk (" unable to get memory for dev->priv.\n");
-		free_irq(dev->irq, dev);
-		return -ENOMEM;
-	}
-
 	/* OK, were are certain this is going to work.  Setup the device. */
 	request_region(ioaddr, WD_IO_EXTENT, model_name);
 
@@ -294,7 +299,7 @@
 	ei_status.block_output = &wd_block_output;
 	ei_status.get_8390_hdr = &wd_get_8390_hdr;
 	dev->open = &wd_open;
-	dev->stop = &wd_close_card;
+	dev->stop = &wd_close;
 	NS8390_init(dev, 0);
 
 #if 1
@@ -414,7 +419,7 @@
 
 
 static int
-wd_close_card(struct device *dev)
+wd_close(struct device *dev)
 {
 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
 
@@ -479,12 +484,15 @@
 		}
 		if (register_netdev(dev) != 0) {
 			printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
-			if (found != 0) return 0;	/* Got at least one. */
+			if (found != 0) {	/* Got at least one. */
+				lock_8390_module();
+				return 0;
+			}
 			return -ENXIO;
 		}
 		found++;
 	}
-
+	lock_8390_module();
 	return 0;
 }
 
@@ -496,12 +504,14 @@
 	for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
 		struct device *dev = &dev_wd[this_dev];
 		if (dev->priv != NULL) {
+			void *priv = dev->priv;
 			int ioaddr = dev->base_addr - WD_NIC_OFFSET;
-			unregister_netdev(dev);
-			kfree(dev->priv);
-			dev->priv = NULL;
 			free_irq(dev->irq, dev);
 			release_region(ioaddr, WD_IO_EXTENT);
+			dev->priv = NULL;
+			unregister_netdev(dev);
+			kfree(priv);
+			unlock_8390_module();
 		}
 	}
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov