patch-2.2.8 linux/drivers/net/eexpress.c

Next file: linux/drivers/net/epic100.c
Previous file: linux/drivers/net/de4x5.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.7/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
@@ -83,6 +83,7 @@
  * practice.
  */
   
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -107,6 +108,8 @@
 #include <linux/skbuff.h>
 #include <linux/malloc.h>
 
+#include <asm/spinlock.h>
+
 #ifndef NET_DEBUG
 #define NET_DEBUG 4
 #endif
@@ -141,6 +144,7 @@
 	unsigned char width;         /* 0 for 16bit, 1 for 8bit */
 	unsigned char was_promisc;
 	unsigned char old_mc_count;
+	spinlock_t lock;
 };
 
 /* This is the code and data that is downloaded to the EtherExpress card's
@@ -502,6 +506,7 @@
 static int eexp_xmit(struct sk_buff *buf, struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
+	unsigned long flags;
 
 #if NET_DEBUG > 6
 	printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
@@ -509,6 +514,15 @@
 
 	disable_irq(dev->irq);
 
+	/*
+	 *	Best would be to use synchronize_irq(); spin_lock() here
+	 *	lets make it work first..
+	 */
+	 
+#ifdef CONFIG_SMP
+	spin_lock_irqsave(&lp->lock, flags);
+#endif
+
 	/* If dev->tbusy is set, all our tx buffers are full but the kernel
 	 * is calling us anyway.  Check that nothing bad is happening.
 	 */
@@ -516,7 +530,13 @@
 		int status = scb_status(dev);
   		unstick_cu(dev);
 		if ((jiffies - lp->last_tx) < HZ)
+		{
+#ifdef CONFIG_SMP
+			spin_unlock_irqrestore(&lp->lock, flags);
+#endif
+
 			return 1;
+		}
 		printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
 		       (SCB_complete(status)?"lost interrupt":
 			"board on fire"));
@@ -544,6 +564,9 @@
 	        eexp_hw_tx_pio(dev,data,length);
 	}
 	dev_kfree_skb(buf);
+#ifdef CONFIG_SMP
+	spin_unlock_irqrestore(&lp->lock, flags);
+#endif
 	enable_irq(dev->irq);
 	return 0;
 }
@@ -646,11 +669,14 @@
 	lp = (struct net_local *)dev->priv;
 	ioaddr = dev->base_addr;
 
+	spin_lock(&lp->lock);
+
 	old_read_ptr = inw(ioaddr+READ_PTR);
 	old_write_ptr = inw(ioaddr+WRITE_PTR);
 
 	outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
 
+	
 	dev->interrupt = 1;
 
 	status = scb_status(dev);
@@ -726,6 +752,8 @@
 #endif
 	outw(old_read_ptr, ioaddr+READ_PTR);
 	outw(old_write_ptr, ioaddr+WRITE_PTR);
+	
+	spin_unlock(&lp->lock);
 	return;
 }
 

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