aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-09-01 18:53:48 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-06 11:19:23 -0400
commit29365c900963d4986b74a0dadea46872bf283d76 (patch)
treed896de1c7306f0f03c9781cb054bbcd5cf0a9817 /drivers/net/skge.c
parentc54f9765daafe8493dba837b3d70e97432cd876a (diff)
[PATCH] skge: irq lock race
The driver needs to access the IRQ status inside of lock to avoid races with other places changing IRQ mask etc. This may be related to some of the SMP bugs reported against skge in kernel bugzilla. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r--drivers/net/skge.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e86a88aa9d0..8a321be2483 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2891,13 +2891,15 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2891{ 2891{
2892 struct skge_hw *hw = dev_id; 2892 struct skge_hw *hw = dev_id;
2893 u32 status; 2893 u32 status;
2894 int handled = 0;
2894 2895
2896 spin_lock(&hw->hw_lock);
2895 /* Reading this register masks IRQ */ 2897 /* Reading this register masks IRQ */
2896 status = skge_read32(hw, B0_SP_ISRC); 2898 status = skge_read32(hw, B0_SP_ISRC);
2897 if (status == 0) 2899 if (status == 0)
2898 return IRQ_NONE; 2900 goto out;
2899 2901
2900 spin_lock(&hw->hw_lock); 2902 handled = 1;
2901 status &= hw->intr_mask; 2903 status &= hw->intr_mask;
2902 if (status & IS_EXT_REG) { 2904 if (status & IS_EXT_REG) {
2903 hw->intr_mask &= ~IS_EXT_REG; 2905 hw->intr_mask &= ~IS_EXT_REG;
@@ -2959,9 +2961,10 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2959 2961
2960 skge_write32(hw, B0_IMSK, hw->intr_mask); 2962 skge_write32(hw, B0_IMSK, hw->intr_mask);
2961 skge_read32(hw, B0_IMSK); 2963 skge_read32(hw, B0_IMSK);
2964out:
2962 spin_unlock(&hw->hw_lock); 2965 spin_unlock(&hw->hw_lock);
2963 2966
2964 return IRQ_HANDLED; 2967 return IRQ_RETVAL(handled);
2965} 2968}
2966 2969
2967#ifdef CONFIG_NET_POLL_CONTROLLER 2970#ifdef CONFIG_NET_POLL_CONTROLLER