--- olympic.h.orig Mon Jan 10 15:50:10 2000 +++ olympic.h Mon Jan 10 15:51:31 2000 @@ -244,6 +244,8 @@ __u8 *olympic_mmio; __u8 *olympic_lap; + spinlock_t olympic_lock ; + volatile int srb_queued; /* True if an SRB is still posted */ struct wait_queue *srb_wait; --- olympic.c.orig Mon Jan 10 15:50:20 2000 +++ olympic.c Mon Jan 10 16:01:05 2000 @@ -23,10 +23,11 @@ * 6/8/99 - Official Release 0.2.0 * Merged into the kernel code * - * To Do: - * - * Sanitize for smp + * 1/10/00 - Added Spinlocks for smp. * + * To Do: + * IPv6 Multicast + * * If Problems do Occur * Most problems can be rectified by either closing and opening the interface * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult @@ -71,6 +72,7 @@ #include #include #include +#include #include "olympic.h" @@ -83,7 +85,7 @@ */ static char *version = -"Olympic.c v0.2.0 6/8/99 - Peter De Schrijver & Mike Phillips" ; +"Olympic.c v0.2.1 1/10/00 - Peter De Schrijver & Mike Phillips" ; static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion", "Address Verification", "Neighbor Notification (Ring Poll)", @@ -245,6 +247,8 @@ } } + spin_lock_init(&olympic_priv->olympic_lock) ; + #if OLYMPIC_DEBUG printk("BCTL: %x\n",readl(olympic_mmio+BCTL)); printk("GPR: %x\n",readw(olympic_mmio+GPR)); @@ -751,6 +755,8 @@ if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ return ; + spin_lock(&olympic_priv->olympic_lock) ; + if (dev->interrupt) printk(KERN_WARNING "%s: Re-entering interrupt \n",dev->name) ; @@ -829,15 +835,19 @@ dev->interrupt = 0 ; writel(SISR_MI,olympic_mmio+SISR_MASK_SUM); - + spin_unlock(&olympic_priv->olympic_lock) ; } static int olympic_xmit(struct sk_buff *skb, struct device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; - __u8 *olympic_mmio=olympic_priv->olympic_mmio; + __u8 *olympic_mmio=olympic_priv->olympic_mmio; + unsigned long flags ; + + spin_lock_irqsave(&olympic_priv->olympic_lock, flags) ; if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; return 1; } @@ -854,10 +864,12 @@ writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1); dev->tbusy=0; - + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; return 0; - } else + } else { + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; return 1; + } }