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:
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:
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,
#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)
#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)
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;
}
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;
//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){
#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
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;
/*
* 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,
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) {