Token Ring + SMP kernel 2.2.3 - PATCH

Tim Hockin (tphocki@www.orl.ilstu.edu)
Thu, 11 Mar 1999 11:16:09 -0600 (EST)


The IBM Token Ring driver has SMP problems in kernels 2.2.x. The attached
patch spinlocks the TR device, and (I think) does "The Right Thing". I am
running it on my 2-way token ring system now, and it seems to be OK.
Please let me know if the patch is not "correct" as I'd like to know more
;)

The maintainer may want to increment the revision number to reflect the 2.2.3
kernel (which this is against, if it matters).

I wasn't sure exactly who to send this to, so if you got it and didn't want
it, sorry :)

Tim

diff -ruN linux-clean/drivers/net/ibmtr.c linux-2.2.3/drivers/net/ibmtr.c
--- linux-clean/drivers/net/ibmtr.c Mon Jan 25 00:04:02 1999
+++ linux-2.2.3/drivers/net/ibmtr.c Thu Mar 11 10:33:08 1999
@@ -70,6 +70,9 @@
* Changes by Joel Sloan (jjs@c-me.com) :
* + disable verbose debug messages by default - to enable verbose
* debugging, edit the IBMTR_DEBUG_MESSAGES define below
+ *
+ * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) :
+ * + added spinlocks for SMP sanity (10 March 1999)
*/

/* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value
@@ -144,6 +147,7 @@
#include <net/checksum.h>

#include <asm/io.h>
+#include <asm/spinlock.h>
#include <asm/system.h>
#include <asm/bitops.h>

@@ -754,6 +758,9 @@
{
struct tok_info *ti=(struct tok_info *)dev->priv;

+ /* init the spinlock */
+ ti->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+
if (ti->open_status==CLOSED) tok_init_card(dev);

if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
@@ -806,6 +813,7 @@
DPRINTK("Int from tok_driver, dev : %p\n",dev);
#endif
ti = (struct tok_info *) dev->priv;
+ spin_lock(&(ti->lock));

/* Disable interrupts till processing is finished */
dev->interrupt=1;
@@ -832,6 +840,7 @@
if (status == 0xFF)
{
DPRINTK("PCMCIA card removed.\n");
+ spin_unlock(&(ti->lock));
dev->interrupt = 0;
return;
}
@@ -840,6 +849,7 @@
if ( readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
{
DPRINTK("PCMCIA card removed.\n");
+ spin_unlock(&(ti->lock));
dev->interrupt = 0;
return;
}
@@ -1167,6 +1177,7 @@
DPRINTK("Unexpected interrupt from tr adapter\n");

}
+ spin_unlock(&(ti->lock));
}

static void initial_tok_int(struct device *dev)
@@ -1598,12 +1609,19 @@
if (test_and_set_bit(0,(void *)&dev->tbusy)!=0)
DPRINTK("Transmitter access conflict\n");
else {
+ int flags;
+
+ /* lock against other CPUs */
+ spin_lock_irqsave(&(ti->lock), flags);
+
/* Save skb; we'll need it when the adapter asks for the data */
ti->current_skb=skb;
writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
writew(ti->exsap_station_id, ti->srb
+offsetof(struct srb_xmit, station_id));
writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
+ spin_unlock_irqrestore(&(ti->lock), flags);
+
dev->trans_start=jiffies;
}

diff -ruN linux-clean/drivers/net/ibmtr.h linux-2.2.3/drivers/net/ibmtr.h
--- linux-clean/drivers/net/ibmtr.h Mon Jul 27 01:35:56 1998
+++ linux-2.2.3/drivers/net/ibmtr.h Wed Mar 10 17:49:36 1999
@@ -217,6 +217,7 @@
unsigned char ring_speed;
__u32 func_addr;
unsigned int retry_count;
+ spinlock_t lock; /* SMP protection */
};

/* token ring adapter commands */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/