]> Pileus Git - ~andy/linux/blobdiff - drivers/net/ethernet/intel/e1000e/ich8lan.c
e1000e: locking bug introduced by commit 67fd4fcb
[~andy/linux] / drivers / net / ethernet / intel / e1000e / ich8lan.c
index 4f709749dbce0299e74076c2c56abd1fccbd8b65..6a17c62cb86f5ad5210d9b5a1452b00995e7da7d 100644 (file)
@@ -852,8 +852,6 @@ static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
        mutex_unlock(&nvm_mutex);
 }
 
-static DEFINE_MUTEX(swflag_mutex);
-
 /**
  *  e1000_acquire_swflag_ich8lan - Acquire software control flag
  *  @hw: pointer to the HW structure
@@ -866,7 +864,12 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
        u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
        s32 ret_val = 0;
 
-       mutex_lock(&swflag_mutex);
+       if (test_and_set_bit(__E1000_ACCESS_SHARED_RESOURCE,
+                            &hw->adapter->state)) {
+               WARN(1, "e1000e: %s: contention for Phy access\n",
+                    hw->adapter->netdev->name);
+               return -E1000_ERR_PHY;
+       }
 
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -878,7 +881,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
        }
 
        if (!timeout) {
-               e_dbg("SW/FW/HW has locked the resource for too long.\n");
+               e_dbg("SW has already locked the resource.\n");
                ret_val = -E1000_ERR_CONFIG;
                goto out;
        }
@@ -898,7 +901,9 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
        }
 
        if (!timeout) {
-               e_dbg("Failed to acquire the semaphore.\n");
+               e_dbg("Failed to acquire the semaphore, FW or HW has it: "
+                     "FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n",
+                     er32(FWSM), extcnf_ctrl);
                extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
                ew32(EXTCNF_CTRL, extcnf_ctrl);
                ret_val = -E1000_ERR_CONFIG;
@@ -907,7 +912,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
 out:
        if (ret_val)
-               mutex_unlock(&swflag_mutex);
+               clear_bit(__E1000_ACCESS_SHARED_RESOURCE, &hw->adapter->state);
 
        return ret_val;
 }
@@ -932,7 +937,7 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
                e_dbg("Semaphore unexpectedly released by sw/fw/hw\n");
        }
 
-       mutex_unlock(&swflag_mutex);
+       clear_bit(__E1000_ACCESS_SHARED_RESOURCE, &hw->adapter->state);
 }
 
 /**
@@ -3139,7 +3144,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        msleep(20);
 
        if (!ret_val)
-               mutex_unlock(&swflag_mutex);
+               clear_bit(__E1000_ACCESS_SHARED_RESOURCE, &hw->adapter->state);
 
        if (ctrl & E1000_CTRL_PHY_RST) {
                ret_val = hw->phy.ops.get_cfg_done(hw);