patch-2.2.3 linux/drivers/net/smc-ultra.c

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

diff -u --recursive --new-file v2.2.2/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
@@ -2,7 +2,7 @@
 /*
 	This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards.
 
-	Written 1993-1996 by Donald Becker.
+	Written 1993-1998 by Donald Becker.
 
 	Copyright 1993 United States Government as represented by the
 	Director, National Security Agency.
@@ -14,7 +14,7 @@
 	Center of Excellence in Space Data and Information Sciences
 		Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
 
-	This driver uses the cards in the 8390-compatible, shared memory mode.
+	This driver uses the cards in the 8390-compatible mode.
 	Most of the run-time complexity is handled by the generic code in
 	8390.c.  The code in this file is responsible for
 
@@ -27,6 +27,8 @@
 
 		ultra_block_input()		Routines for reading and writing blocks of
 		ultra_block_output()	packet buffer memory.
+		ultra_pio_input()
+		ultra_pio_output()
 
 	This driver enables the shared memory only when doing the actual data
 	transfers to avoid a bug in early version of the card that corrupted
@@ -34,7 +36,7 @@
 
 	This driver now supports the programmed-I/O (PIO) data transfer mode of
 	the EtherEZ. It does not use the non-8390-compatible "Altego" mode.
-	That support (if available) is smc-ez.c.
+	That support (if available) is in smc-ez.c.
 
 	Changelog:
 
@@ -44,8 +46,7 @@
 */
 
 static const char *version =
-	"smc-ultra.c:v2.00 6/6/96 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
+	"smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
 
@@ -75,13 +76,13 @@
 static void ultra_block_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
 static void ultra_block_output(struct device *dev, int count,
-							const unsigned char *buf, int start_page);
+							const unsigned char *buf, const int start_page);
 static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 						int ring_page);
 static void ultra_pio_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
 static void ultra_pio_output(struct device *dev, int count,
-							const unsigned char *buf, int start_page);
+							 const unsigned char *buf, const int start_page);
 static int ultra_close_card(struct device *dev);
 
 
@@ -155,11 +156,8 @@
 	if (load_8390_module("smc-ultra.c"))
 		return -ENOSYS;
 
-	/* We should have a "dev" from Space.c or the static module table. */
-	if (dev == NULL) {
-		printk("smc-ultra.c: Passed a NULL device.\n");
+	if (dev == NULL)
 		dev = init_etherdev(0, 0);
-	}
 
 	if (ei_debug  &&  version_printed++ == 0)
 		printk(version);
@@ -255,12 +253,19 @@
 ultra_open(struct device *dev)
 {
 	int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
+	unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40,
+							   0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, };
 
 	if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev))
 		return -EAGAIN;
 
 	outb(0x00, ioaddr);	/* Disable shared memory for safety. */
 	outb(0x80, ioaddr + 5);
+	/* Set the IRQ line. */
+	outb(inb(ioaddr + 4) | 0x80, ioaddr + 4);
+	outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13);
+	outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4);
+
 	if (ei_status.block_input == &ultra_pio_input) {
 		outb(0x11, ioaddr + 6);		/* Enable interrupts and PIO. */
 		outb(0x01, ioaddr + 0x19);  	/* Enable ring read auto-wrap. */
@@ -358,7 +363,7 @@
    byte-sequentially to IOPA, with no intervening I/O operations, and the
    data is read or written to the IOPD data port.
    The only potential complication is that the address register is shared
-   must be always be rewritten between each read/write direction change.
+   and must be always be rewritten between each read/write direction change.
    This is no problem for us, as the 8390 code ensures that we are single
    threaded. */
 static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
@@ -379,20 +384,17 @@
 	/* For now set the address again, although it should already be correct. */
 	outb(ring_offset, ioaddr + IOPA);	/* Set the address, LSB first. */
 	outb(ring_offset >> 8, ioaddr + IOPA);
+	/* We know skbuffs are padded to at least word alignment. */
 	insw(ioaddr + IOPD, buf, (count+1)>>1);
-#ifdef notdef
-	/* We don't need this -- skbuffs are padded to at least word alignment. */
-	if (count & 0x01) {
-		buf[count-1] = inb(ioaddr + IOPD);
-#endif
 }
 
 static void ultra_pio_output(struct device *dev, int count,
-							const unsigned char *buf, int start_page)
+							const unsigned char *buf, const int start_page)
 {
 	int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
 	outb(0x00, ioaddr + IOPA);	/* Set the address, LSB first. */
 	outb(start_page, ioaddr + IOPA);
+	/* An extra odd byte is OK here as well. */
 	outsw(ioaddr + IOPD, buf, (count+1)>>1);
 }
 
@@ -461,15 +463,12 @@
 		}
 		if (register_netdev(dev) != 0) {
 			printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-			if (found != 0) {	/* Got at least one. */
-				lock_8390_module();
-				return 0;
-			}
+			if (found != 0) return 0;	/* Got at least one. */
 			return -ENXIO;
 		}
 		found++;
 	}
-	lock_8390_module();
+
 	return 0;
 }
 
@@ -481,15 +480,14 @@
 	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
 		struct device *dev = &dev_ultra[this_dev];
 		if (dev->priv != NULL) {
+			/* NB: ultra_close_card() does free_irq + irq2dev */
 			int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-			void *priv = dev->priv;
-			/* NB: ultra_close_card() does free_irq */
+			kfree(dev->priv);
+			dev->priv = NULL;
 			release_region(ioaddr, ULTRA_IO_EXTENT);
 			unregister_netdev(dev);
-			kfree(priv);
 		}
 	}
-	unlock_8390_module();
 }
 #endif /* MODULE */
 
@@ -500,6 +498,7 @@
  *  version-control: t
  *  kept-new-versions: 5
  *  c-indent-level: 4
+ *  c-basic-offset: 4
  *  tab-width: 4
  * End:
  */

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