Commit 09bdfb05 authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (6/8) arlan -- add spinlock

Convert bogus test_and_set local wait, to a real spin_lock so it
has a chance of working on an SMP.  This also does the right thing
and locks out interrupts while giving commands on UP;  maybe the
comment in Kconfig was because there was never a proper mutex...

Don't have real hardware to try this, but it can't be worse than
the previous code.
parent 48a1db9a
......@@ -44,7 +44,6 @@ static int txScrambled = 1;
static int mdebug;
#endif
#if LINUX_VERSION_CODE > 0x20100
MODULE_PARM(irq, "i");
MODULE_PARM(mem, "i");
MODULE_PARM(probe, "i");
......@@ -87,10 +86,6 @@ MODULE_PARM_DESC(arlan_exit_debug, "(ignored)");
MODULE_PARM_DESC(arlan_entry_and_exit_debug, "(ignored)");
#endif
#else
#define test_and_set_bit set_bit
#endif
struct arlan_conf_stru arlan_conf[MAX_ARLANS];
static int arlans_found;
......@@ -172,6 +167,7 @@ int arlan_command(struct net_device *dev, int command_p)
int udelayed = 0;
int i = 0;
long long time_mks = arlan_time();
unsigned long flags;
ARLAN_DEBUG_ENTRY("arlan_command");
......@@ -179,8 +175,8 @@ int arlan_command(struct net_device *dev, int command_p)
priv->card_polling_interval = 1;
if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
printk(KERN_DEBUG "arlan_command, %lx lock %lx commandByte %x waiting %x incoming %x \n",
jiffies, priv->command_lock, READSHMB(arlan->commandByte),
printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %x incoming %x \n",
jiffies, READSHMB(arlan->commandByte),
priv->waiting_command_mask, command_p);
priv->waiting_command_mask |= command_p;
......@@ -201,13 +197,8 @@ int arlan_command(struct net_device *dev, int command_p)
}
/* Card access serializing lock */
spin_lock_irqsave(&priv->lock, flags);
if (test_and_set_bit(0, (void *) &priv->command_lock))
{
if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
printk(KERN_DEBUG "arlan_command: entered when command locked \n");
goto command_busy_end;
}
/* Check cards status and waiting */
if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
......@@ -475,7 +466,7 @@ int arlan_command(struct net_device *dev, int command_p)
if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
printk(KERN_ERR "card busy leaving command %x \n", priv->waiting_command_mask);
priv->command_lock = 0;
spin_unlock_irqrestore(&priv->lock, flags);
ARLAN_DEBUG_EXIT("arlan_command");
priv->last_command_buff_free_time = jiffies;
return 0;
......@@ -486,24 +477,17 @@ int arlan_command(struct net_device *dev, int command_p)
if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
printk(KERN_ERR "%s arlan_command card busy end \n", dev->name);
priv->command_lock = 0;
spin_unlock_irqrestore(&priv->lock, flags);
ARLAN_DEBUG_EXIT("arlan_command");
return 1;
bad_end:
printk(KERN_ERR "%s arlan_command bad end \n", dev->name);
priv->command_lock = 0;
spin_unlock_irqrestore(&priv->lock, flags);
ARLAN_DEBUG_EXIT("arlan_command");
return -1;
command_busy_end:
if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
printk(KERN_ERR "%s arlan_command command busy end \n", dev->name);
ARLAN_DEBUG_EXIT("arlan_command");
return 2;
}
static inline void arlan_command_process(struct net_device *dev)
......@@ -1238,7 +1222,7 @@ static int arlan_open(struct net_device *dev)
memset(dev->broadcast, 0xff, 6);
dev->tx_queue_len = tx_queue_len;
priv->interrupt_processing_active = 0;
priv->command_lock = 0;
spin_lock_init(&priv->lock);
netif_start_queue (dev);
......
......@@ -367,7 +367,7 @@ struct arlan_private {
volatile long long tx_last_cleared;
volatile int retransmissions;
volatile int interrupt_ack_requested;
volatile long command_lock;
spinlock_t lock;
volatile int rx_command_needed;
volatile int tx_command_needed;
volatile int waiting_command_mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment