Import 2.3.18pre1
[davej-history.git] / drivers / net / 3c507.c
index f6332d9..3ad87d4 100644 (file)
@@ -40,6+40,7 @@ static const char *version =
        info that the casual reader might think that it documents the i82586 :-<.
 */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -49,6+50,7 @@ static const char *version =
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/string.h>
+#include <linux/spinlock.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -123,6+125,7 @@ struct net_local {
        ushort tx_head;
        ushort tx_cmd_link;
        ushort tx_reap;
+       spinlock_t lock;
 };
 
 /*
@@ -276,18+279,18 @@ static unsigned short init_words[] = {
 
 /* Index to functions, as function prototypes. */
 
-extern int el16_probe(struct device *dev);     /* Called from Space.c */
+extern int el16_probe(struct net_device *dev); /* Called from Space.c */
 
-static int     el16_probe1(struct device *dev, int ioaddr);
-static int     el16_open(struct device *dev);
-static int     el16_send_packet(struct sk_buff *skb, struct device *dev);
+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);
 static void    el16_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void el16_rx(struct device *dev);
-static int     el16_close(struct device *dev);
-static struct net_device_stats *el16_get_stats(struct device *dev);
+static void el16_rx(struct net_device *dev);
+static int     el16_close(struct net_device *dev);
+static struct net_device_stats *el16_get_stats(struct net_device *dev);
 
-static void hardware_send_packet(struct device *dev, void *buf, short length);
-static void init_82586_mem(struct device *dev);
+static void hardware_send_packet(struct net_device *dev, void *buf, short length);
+static void init_82586_mem(struct net_device *dev);
 
 \f
 #ifdef HAVE_DEVLIST
@@ -302,7+305,7 @@ struct netdev_entry netcard_drv =
        device and return success.
        */
 
-__initfunc(int el16_probe(struct device *dev))
+int __init el16_probe(struct net_device *dev)
 {
        int base_addr = dev ? dev->base_addr : 0;
        int i;
@@ -323,7+326,7 @@ __initfunc(int el16_probe(struct device *dev))
        return ENODEV;
 }
 
-__initfunc(int el16_probe1(struct device *dev, int ioaddr))
+int __init el16_probe1(struct net_device *dev, int ioaddr)
 {
        static unsigned char init_ID_done = 0, version_printed = 0;
        int i, irq, irqval;
@@ -429,7+432,7 @@ __initfunc(int el16_probe1(struct device *dev, int ioaddr))
        return 0;
 }
 
-static int el16_open(struct device *dev)
+static int el16_open(struct net_device *dev)
 {
        /* Initialize the 82586 memory and start it. */
        init_82586_mem(dev);
@@ -443,11+446,12 @@ static int el16_open(struct device *dev)
        return 0;
 }
 
-static int el16_send_packet(struct sk_buff *skb, struct device *dev)
+static int el16_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        int ioaddr = dev->base_addr;
        unsigned long shmem = dev->mem_start;
+       unsigned long flags;
 
        if (dev->tbusy) 
        {
@@ -487,7+491,13 @@ static int el16_send_packet(struct sk_buff *skb, struct device *dev)
                lp->stats.tx_bytes+=length;
                /* Disable the 82586's input to the interrupt line. */
                outb(0x80, ioaddr + MISC_CTRL);
+#ifdef CONFIG_SMP
+               spin_lock_irqsave(&lp->lock, flags);
                hardware_send_packet(dev, buf, length);
+               spin_unlock_irqrestore(&lp->lock, flags);
+#else
+               hardware_send_packet(dev, buf, length);
+#endif         
                dev->trans_start = jiffies;
                /* Enable the 82586 interrupt input. */
                outb(0x84, ioaddr + MISC_CTRL);
@@ -504,7+514,7 @@ static int el16_send_packet(struct sk_buff *skb, struct device *dev)
        Handle the network interface interrupts. */
 static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       struct device *dev = dev_id;
+       struct net_device *dev = dev_id;
        struct net_local *lp;
        int ioaddr, status, boguscount = 0;
        ushort ack_cmd = 0;
@@ -515,11+525,14 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                return;
        }
        dev->interrupt = 1;
+       
 
        ioaddr = dev->base_addr;
        lp = (struct net_local *)dev->priv;
        shmem = dev->mem_start;
 
+       spin_lock(&lp->lock);
+
        status = readw(shmem+iSCB_STATUS);
 
        if (net_debug > 4) {
@@ -579,7+592,7 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if ((status & 0x0070) != 0x0040  &&  dev->start) 
        {
-               static void init_rx_bufs(struct device *);
+               static void init_rx_bufs(struct net_device *);
                /* The Rx unit is not ready, it must be hung.  Restart the receiver by
                   initializing the rx buffers, and issuing an Rx start command. */
                if (net_debug)
@@ -598,11+611,12 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        /* Enable the 82586's interrupt input. */
        outb(0x84, ioaddr + MISC_CTRL);
+       spin_unlock(&lp->lock);
 
        return;
 }
 
-static int el16_close(struct device *dev)
+static int el16_close(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
        unsigned long shmem = dev->mem_start;
@@ -628,7+642,7 @@ static int el16_close(struct device *dev)
 
 /* Get the current statistics. This may be called with the card open or
    closed. */
-static struct net_device_stats *el16_get_stats(struct device *dev)
+static struct net_device_stats *el16_get_stats(struct net_device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
 
@@ -638,7+652,7 @@ static struct net_device_stats *el16_get_stats(struct device *dev)
 }
 
 /* Initialize the Rx-block list. */
-static void init_rx_bufs(struct device *dev)
+static void init_rx_bufs(struct net_device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned long write_ptr;
@@ -681,7+695,7 @@ static void init_rx_bufs(struct device *dev)
        writew(lp->rx_head,write_ptr+2);                        /* Link */
 }
 
-static void init_82586_mem(struct device *dev)
+static void init_82586_mem(struct net_device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        short ioaddr = dev->base_addr;
@@ -739,7+753,7 @@ static void init_82586_mem(struct device *dev)
        return;
 }
 
-static void hardware_send_packet(struct device *dev, void *buf, short length)
+static void hardware_send_packet(struct net_device *dev, void *buf, short length)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        short ioaddr = dev->base_addr;
@@ -784,7+798,7 @@ static void hardware_send_packet(struct device *dev, void *buf, short length)
                dev->tbusy = 0;
 }
 
-static void el16_rx(struct device *dev)
+static void el16_rx(struct net_device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned long shmem = dev->mem_start;
@@ -855,7+869,7 @@ static void el16_rx(struct device *dev)
 }
 #ifdef MODULE
 static char devicename[9] = { 0, };
-static struct device dev_3c507 = {
+static struct net_device dev_3c507 = {
        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,
close