]> Pileus Git - ~andy/linux/commitdiff
igb: Acquire, release semaphore for writing each EEPROM page
authorAkeem G. Abodunrin <akeem.g.abodunrin@intel.com>
Sat, 3 Nov 2012 03:08:41 +0000 (03:08 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 1 Dec 2012 10:49:17 +0000 (02:49 -0800)
This patch allows software acquires and releases NVM resource for
writing each EEPROM page, instead of holding semaphore for the whole
data block which is too long and could trigger write fails on
unpredictable addresses.

Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/igb/e1000_nvm.c

index 7db3f80bcd5713cad349ee566e222315be9d7cd4..fbb7604db364f59729bb3f6c36d41758d4cf40ba 100644 (file)
@@ -438,7 +438,7 @@ out:
 s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
-       s32 ret_val;
+       s32 ret_val = -E1000_ERR_NVM;
        u16 widx = 0;
 
        /*
@@ -448,22 +448,21 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
            (words == 0)) {
                hw_dbg("nvm parameter(s) out of bounds\n");
-               ret_val = -E1000_ERR_NVM;
-               goto out;
+               return ret_val;
        }
 
-       ret_val = hw->nvm.ops.acquire(hw);
-       if (ret_val)
-               goto out;
-
-       msleep(10);
-
        while (widx < words) {
                u8 write_opcode = NVM_WRITE_OPCODE_SPI;
 
-               ret_val = igb_ready_nvm_eeprom(hw);
+               ret_val = nvm->ops.acquire(hw);
                if (ret_val)
-                       goto release;
+                       return ret_val;
+
+               ret_val = igb_ready_nvm_eeprom(hw);
+               if (ret_val) {
+                       nvm->ops.release(hw);
+                       return ret_val;
+               }
 
                igb_standby_nvm(hw);
 
@@ -497,13 +496,10 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
                                break;
                        }
                }
+               usleep_range(1000, 2000);
+               nvm->ops.release(hw);
        }
 
-       msleep(10);
-release:
-       hw->nvm.ops.release(hw);
-
-out:
        return ret_val;
 }