fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / lance.c
index d1d714f..a384332 100644 (file)
@@ -19,7 +19,7 @@
        - alignment problem with 1.3.* kernel and some minor changes.
        Thomas Bogendoerfer (tsbogend@bigbug.franken.de):
        - added support for Linux/Alpha, but removed most of it, because
-        it worked only for the PCI chip. 
+        it worked only for the PCI chip.
       - added hook for the 32bit lance driver
       - added PCnetPCI II (79C970A) to chip table
        Paul Gortmaker (gpg109@rsphy1.anu.edu.au):
@@ -31,7 +31,7 @@
                   before unregister_netdev() which caused NULL pointer
                   reference later in the chain (in rtnetlink_fill_ifinfo())
                   -- Mika Kuoppala <miku@iki.fi>
-    
+
     Forward ported v1.14 to 2.1.129, merged the PCI and misc changes from
     the 2.1 version of the old driver - Alan Cox
 
@@ -42,7 +42,7 @@
        Vesselin Kostadinov <vesok at yahoo dot com > - 22/4/2004
 */
 
-static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
+static const char version[] = "lance.c:v1.16 2006/11/09 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -57,6 +57,7 @@ static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/mm.h>
 #include <linux/bitops.h>
 
 #include <asm/io.h>
@@ -301,13 +302,13 @@ static int lance_open(struct net_device *dev);
 static void lance_init_ring(struct net_device *dev, gfp_t mode);
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lance_rx(struct net_device *dev);
-static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t lance_interrupt(int irq, void *dev_id);
 static int lance_close(struct net_device *dev);
 static struct net_device_stats *lance_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 static void lance_tx_timeout (struct net_device *dev);
 
-\f
+
 
 #ifdef MODULE
 #define MAX_CARDS              8       /* Max number of interfaces (cards) per module */
@@ -326,7 +327,7 @@ MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)");
 MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)");
 MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)");
 
-int init_module(void)
+int __init init_module(void)
 {
        struct net_device *dev;
        int this_dev, found = 0;
@@ -367,14 +368,14 @@ static void cleanup_card(struct net_device *dev)
        kfree(lp);
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
                struct net_device *dev = dev_lance[this_dev];
                if (dev) {
-                       unregister_netdev(dev); 
+                       unregister_netdev(dev);
                        cleanup_card(dev);
                        free_netdev(dev);
                }
@@ -464,20 +465,25 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        static int did_version;                 /* Already printed version info. */
        unsigned long flags;
        int err = -ENOMEM;
+       void __iomem *bios;
 
        /* First we look for special cases.
           Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
           There are two HP versions, check the BIOS for the configuration port.
           This method provided by L. Julliard, Laurent_Julliard@grenoble.hp.com.
           */
-       if (isa_readw(0x000f0102) == 0x5048)  {
+       bios = ioremap(0xf00f0, 0x14);
+       if (!bios)
+               return -ENOMEM;
+       if (readw(bios + 0x12) == 0x5048)  {
                static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
-               int hp_port = (isa_readl(0x000f00f1) & 1)  ? 0x499 : 0x99;
+               int hp_port = (readl(bios + 1) & 1)  ? 0x499 : 0x99;
                /* We can have boards other than the built-in!  Verify this is on-board. */
                if ((inb(hp_port) & 0xc0) == 0x80
                        && ioaddr_table[inb(hp_port) & 3] == ioaddr)
                        hp_builtin = hp_port;
        }
+       iounmap(bios);
        /* We also recognize the HP Vectra on-board here, but check below. */
        hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
                                && inb(ioaddr+2) == 0x09);
@@ -526,7 +532,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
 
        dev->base_addr = ioaddr;
        /* Make certain the data structures used by the LANCE are aligned and DMAble. */
-               
+
        lp = kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
        if(lp==NULL)
                return -ENODEV;
@@ -651,7 +657,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                        outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */
                        if (request_dma(dma, chipname))
                                continue;
-                               
+
                        flags=claim_dma_lock();
                        set_dma_mode(dma, DMA_MODE_CASCADE);
                        enable_dma(dma);
@@ -732,7 +738,7 @@ out_lp:
        return err;
 }
 
-\f
+
 static int
 lance_open(struct net_device *dev)
 {
@@ -796,7 +802,7 @@ lance_open(struct net_device *dev)
        while (i++ < 100)
                if (inw(ioaddr+LANCE_DATA) & 0x0100)
                        break;
-       /* 
+       /*
         * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
         * reports that doing so triggers a bug in the '974.
         */
@@ -821,7 +827,7 @@ lance_open(struct net_device *dev)
    restarting the chip, but I'm too lazy to do so right now.  dplatt@3do.com
 */
 
-static void 
+static void
 lance_purge_ring(struct net_device *dev)
 {
        struct lance_private *lp = dev->priv;
@@ -963,12 +969,11 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* The old LANCE chips doesn't automatically pad buffers to min. size. */
        if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
                if (skb->len < ETH_ZLEN) {
-                       skb = skb_padto(skb, ETH_ZLEN);
-                       if (skb == NULL)
+                       if (skb_padto(skb, ETH_ZLEN))
                                goto out;
                        lp->tx_ring[entry].length = -ETH_ZLEN;
                }
-               else 
+               else
                        lp->tx_ring[entry].length = -skb->len;
        } else
                lp->tx_ring[entry].length = -skb->len;
@@ -1008,22 +1013,16 @@ out:
 }
 
 /* The LANCE interrupt handler. */
-static irqreturn_t
-lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp;
        int csr0, ioaddr, boguscnt=10;
        int must_restart;
 
-       if (dev == NULL) {
-               printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        ioaddr = dev->base_addr;
        lp = dev->priv;
-       
+
        spin_lock (&lp->devlock);
 
        outw(0x00, dev->base_addr + LANCE_ADDR);
@@ -1047,7 +1046,7 @@ lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                        while (dirty_tx < lp->cur_tx) {
                                int entry = dirty_tx & TX_RING_MOD_MASK;
                                int status = lp->tx_ring[entry].base;
-                       
+
                                if (status < 0)
                                        break;                  /* It still hasn't been Txed */
 
@@ -1138,7 +1137,7 @@ lance_rx(struct net_device *dev)
        struct lance_private *lp = dev->priv;
        int entry = lp->cur_rx & RX_RING_MOD_MASK;
        int i;
-               
+
        /* If we own the next entry, it's a new packet. Send it up. */
        while (lp->rx_ring[entry].base >= 0) {
                int status = lp->rx_ring[entry].base >> 24;
@@ -1156,12 +1155,12 @@ lance_rx(struct net_device *dev)
                        if (status & 0x04) lp->stats.rx_fifo_errors++;
                        lp->rx_ring[entry].base &= 0x03ffffff;
                }
-               else 
+               else
                {
                        /* Malloc up new buffer, compatible with net3. */
                        short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4;
                        struct sk_buff *skb;
-                       
+
                        if(pkt_len<60)
                        {
                                printk("%s: Runt packet!\n",dev->name);
@@ -1170,14 +1169,14 @@ lance_rx(struct net_device *dev)
                        else
                        {
                                skb = dev_alloc_skb(pkt_len+2);
-                               if (skb == NULL) 
+                               if (skb == NULL)
                                {
                                        printk("%s: Memory squeeze, deferring packet.\n", dev->name);
                                        for (i=0; i < RX_RING_SIZE; i++)
                                                if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0)
                                                        break;
 
-                                       if (i > RX_RING_SIZE -2) 
+                                       if (i > RX_RING_SIZE -2)
                                        {
                                                lp->stats.rx_dropped++;
                                                lp->rx_ring[entry].base |= 0x80000000;
@@ -1277,8 +1276,6 @@ static void set_multicast_list(struct net_device *dev)
        outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance.  */
 
        if (dev->flags&IFF_PROMISC) {
-               /* Log any net taps. */
-               printk("%s: Promiscuous mode enabled.\n", dev->name);
                outw(15, ioaddr+LANCE_ADDR);
                outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
        } else {