]> git.openfabrics.org - ~adrianc/mstflint.git/commitdiff
- mflash : updated icmd error codes
authorAdrian Chiris <adrianc@mellanox.com>
Tue, 16 Dec 2014 11:46:17 +0000 (13:46 +0200)
committerAdrian Chiris <adrianc@mellanox.com>
Tue, 16 Dec 2014 11:46:17 +0000 (13:46 +0200)
- mtcr_ul : fixed icmd semaphore locking mechanism according to new spec

mflash/mflash.c
mflash/mflash_pack_layer.c
mflash/mflash_types.h
mtcr_ul/mtcr_ul.c
mtcr_ul/mtcr_ul_icmd_cif.c

index 66c5cf9a34850e5cc690ab152edea350d797ebf1..23f174563e6727cd3be45ce40fc1066da478d4bd 100644 (file)
@@ -2502,6 +2502,8 @@ const char*   mf_err2str (int err_code) {
         return "MFE_ICMD_INVALID_CMD";
     case MFE_ICMD_OPERATIONAL_ERROR:
         return "MFE_ICMD_OPERATIONAL_ERROR";
+    case MFE_ICMD_SEMAPHORE_TO:
+        return "MFE_ICMD_SEMAPHORE_TO";
     case MFE_REG_ACCESS_BAD_METHOD:
         return "MFE_REG_ACCESS_BAD_METHOD";
     case MFE_REG_ACCESS_NOT_SUPPORTED:
index 2b2bdf604f97ca88a14398ef33792470f2a4b8bc..37a9c883758199828aee715c4b8956aa609f3ac0 100755 (executable)
@@ -197,7 +197,7 @@ static MfError MError2MfError(MError rc) {
    case ME_ICMD_STATUS_CR_FAIL:
           return MFE_CR_ERROR;
    case ME_ICMD_STATUS_SEMAPHORE_TO:
-          return MFE_CMDIF_TIMEOUT_ERR;
+          return MFE_ICMD_SEMAPHORE_TO;
    case ME_ICMD_STATUS_EXECUTE_TO:
           return MFE_CMDIF_TIMEOUT_ERR;
    case ME_ICMD_STATUS_IFC_BUSY:
index b66f6ef0cb66e77e62e7fef773db67a82529d9a0..d85a28a3227cdb5dc54e61a75e39cf0de6fc4278 100644 (file)
@@ -82,6 +82,7 @@ typedef enum MfError {
     MFE_ICMD_INVALID_OPCODE,
     MFE_ICMD_INVALID_CMD,
     MFE_ICMD_OPERATIONAL_ERROR,
+    MFE_ICMD_SEMAPHORE_TO,
 
     MFE_REG_ACCESS_BAD_METHOD,
     MFE_REG_ACCESS_NOT_SUPPORTED,
index cfacc7de02d5219471ac45cc453c20dc4740f7fd..9c00ffe3a7621e33d680a3e9f5f428814bcb5d2c 100644 (file)
@@ -672,12 +672,23 @@ enum {
 #define READ4_PCI(mf, val_ptr, pci_offs, err_prefix, action_on_fail)    \
     do {                                                                \
         int rc;                                                         \
+        int lock_rc;                                                    \
         struct pciconf_context *pci_ctx = mf->ctx;                      \
+        lock_rc = _flock_int(mf->fdlock, LOCK_EX);                      \
+        if (lock_rc) {                                                  \
+            perror(err_prefix);                                         \
+            action_on_fail;                                             \
+        }                                                               \
         rc = pread(pci_ctx->fd, val_ptr, 4, pci_offs);                  \
+        lock_rc = _flock_int(mf->fdlock, LOCK_UN);                      \
+        if (lock_rc) {                                                  \
+            perror(err_prefix);                                         \
+            action_on_fail;                                             \
+        }                                                               \
         if (rc != 4 ) {                                                 \
             if (rc < 0)                                                 \
                 perror(err_prefix);                                     \
-                action_on_fail;                                         \
+            action_on_fail;                                             \
         }                                                               \
         *val_ptr = __le32_to_cpu(*val_ptr);\
     } while (0)
@@ -685,14 +696,25 @@ enum {
 #define WRITE4_PCI(mf, val, pci_offs, err_prefix, action_on_fail)           \
         do {                                                                \
             int rc;                                                         \
+            int lock_rc;                                                    \
             u_int32_t val_le;                                               \
             struct pciconf_context *pci_ctx = mf->ctx;                      \
-            val_le = __cpu_to_le32(val);                             \
+            val_le = __cpu_to_le32(val);                                    \
+            lock_rc = _flock_int(mf->fdlock, LOCK_EX);                      \
+            if (lock_rc) {                                                  \
+                perror(err_prefix);                                         \
+                action_on_fail;                                             \
+            }                                                               \
             rc = pwrite(pci_ctx->fd, &val_le, 4, pci_offs);                 \
+            lock_rc = _flock_int(mf->fdlock, LOCK_UN);                      \
+            if (lock_rc) {                                                  \
+                perror(err_prefix);                                         \
+                action_on_fail;                                             \
+            }                                                               \
             if (rc != 4 ) {                                                 \
                 if (rc < 0)                                                 \
                     perror(err_prefix);                                     \
-                    action_on_fail;                                         \
+                action_on_fail;                                         \
             }                                                               \
         } while (0)
 
@@ -703,20 +725,44 @@ int pci_find_capability(mfile* mf, int cap_id)
     unsigned char visited[256] = {}; /* Prevent infinite loops */
     unsigned char data[2];
     int ret;
+    int lock_ret;
     struct pciconf_context *pci_ctx = mf->ctx;
 
+    // protect against parallel access
+    lock_ret = _flock_int(mf->fdlock, LOCK_EX);
+    if (lock_ret) {
+        return 0;
+    }
+
     ret = pread(pci_ctx->fd, data, 1, PCI_CAP_PTR);
+
+    lock_ret = _flock_int(mf->fdlock, LOCK_UN);
+    if (lock_ret) {
+        return 0;
+    }
+
     if (ret != 1) {
         return 0;
     }
-    offset = data[0];
 
+    offset = data[0];
     while(1) {
         if (offset < PCI_HDR_SIZE || offset > PCI_EXT_SPACE_ADDR) {
             return 0;
         }
 
+        lock_ret = _flock_int(mf->fdlock, LOCK_EX);
+        if (lock_ret) {
+            return 0;
+        }
+
         ret = pread(pci_ctx->fd, data, sizeof data, offset);
+
+        lock_ret = _flock_int(mf->fdlock, LOCK_UN);
+        if (lock_ret) {
+            return 0;
+        }
+
         if (ret != sizeof data) {
             return 0;
         }
@@ -1010,8 +1056,9 @@ int mtcr_pciconf_open(mfile *mf, const char *name)
 
     ctx->fd = -1;
     ctx->fd = open(name, O_RDWR | O_SYNC);
-    if (ctx->fd < 0)
+    if (ctx->fd < 0) {
         return -1;
+    }
 
     mf->access_type   = MTCR_ACCESS_CONFIG;
 
@@ -1824,7 +1871,6 @@ int maccess_reg(mfile     *mf,
        //reg too big
        return ME_REG_ACCESS_SIZE_EXCCEEDS_LIMIT;
     }
-
     // TODO: add specific checks for each FW access method where needed
 #ifndef MST_UL
     if (mf->flags & MDEVS_MLNX_OS){
index a9b93e2c60690a050bd496ead83fb2753e07c89d..94c85bc9f8520d28ebf01ed46c72061fa3d97b61 100644 (file)
 #include <common/tools_utils.h>
 #include "mtcr_icmd_cif.h"
 
+#ifdef __WIN__
+#include <process.h>
+#define getpid() _getpid()
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
 //#define _DEBUG_MODE   // un-comment this to enable debug prints
 
 #define IN
@@ -306,7 +314,6 @@ int icmd_clear_semaphore(mfile *mf) {
        if ((ret = icmd_open(mf))) {
                return ret;
        }
-
     MWRITE4_SEMAPHORE(mf, mf->icmd.semaphore_addr, 0, return ME_ICMD_STATUS_CR_FAIL);
     mf->icmd.took_semaphore = 0;
     return ME_OK;
@@ -315,31 +322,49 @@ int icmd_clear_semaphore(mfile *mf) {
 /*
  * icmd_take_semaphore
  */
-int icmd_take_semaphore(mfile *mf) {
-       // open icmd interface by demand
-       int ret;
-       if ((ret = icmd_open(mf))) {
-               return ret;
-       }
-    u_int32_t r;
+static int icmd_take_semaphore_com(mfile *mf, u_int32_t expected_read_val)
+{
+    u_int32_t read_val;
     unsigned retries = 0;
 
     DBG_PRINTF("Taking semaphore...\n");
 
-    do {    // loop while the semaphore is taken by someone else
-        if (++retries > 256) {
-            return ME_ICMD_STATUS_SEMAPHORE_TO;
-        }
-        MREAD4_SEMAPHORE(mf, mf->icmd.semaphore_addr, &r, return ME_ICMD_STATUS_CR_FAIL);
-        if (! r)
-            break;
-        msleep(rand() % 20);
-    } while (r);
+     do {    // loop while the semaphore is taken by someone else
+         if (++retries > 256) {
+             return ME_ICMD_STATUS_SEMAPHORE_TO;
+         }
+         if (mf->supp_fw_ifc) {
+             //write expected val before reading it
+             MWRITE4_SEMAPHORE(mf, mf->icmd.semaphore_addr, expected_read_val, return ME_ICMD_STATUS_CR_FAIL);
+         }
+         MREAD4_SEMAPHORE(mf, mf->icmd.semaphore_addr, &read_val, return ME_ICMD_STATUS_CR_FAIL);
+         if (read_val == expected_read_val)
+             break;
+         msleep(rand() % 20);
+     } while (read_val != expected_read_val);
+
+     mf->icmd.took_semaphore = 1;
+     DBG_PRINTF("Semaphore taken successfully...\n");
 
-    mf->icmd.took_semaphore = 1;
-    DBG_PRINTF("Semaphore taken successfully...\n");
+     return ME_OK;
+}
 
-    return ME_OK;
+int icmd_take_semaphore(mfile *mf)
+{
+    // open icmd interface by demand
+    int ret;
+    if ((ret = icmd_open(mf))) {
+        return ret;
+    }
+    if (!mf->supp_fw_ifc) {
+        return icmd_take_semaphore_com(mf, 0);
+    }
+
+    static u_int32_t pid = 0;
+    if (!pid) {
+        pid = getpid();
+    }
+    return icmd_take_semaphore_com(mf, pid);
 }
 
 int icmd_send_command(mfile    *mf,
@@ -434,7 +459,6 @@ int icmd_open(mfile *mf)
     if (mf->icmd.icmd_opened) {
         return ME_OK;
     }
-
     mf->icmd.took_semaphore = 0;
     // check if we support icmd in virtual CR-Space
     if (mf->supp_fw_ifc) {