From 121b43a0213dbaa5c8fb91a063fa2c10204b0938 Mon Sep 17 00:00:00 2001 From: Adrian Chiris Date: Tue, 16 Dec 2014 13:46:17 +0200 Subject: [PATCH] - mflash : updated icmd error codes - mtcr_ul : fixed icmd semaphore locking mechanism according to new spec --- mflash/mflash.c | 2 ++ mflash/mflash_pack_layer.c | 2 +- mflash/mflash_types.h | 1 + mtcr_ul/mtcr_ul.c | 58 +++++++++++++++++++++++++++++---- mtcr_ul/mtcr_ul_icmd_cif.c | 66 ++++++++++++++++++++++++++------------ 5 files changed, 101 insertions(+), 28 deletions(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index 66c5cf9..23f1745 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -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: diff --git a/mflash/mflash_pack_layer.c b/mflash/mflash_pack_layer.c index 2b2bdf6..37a9c88 100755 --- a/mflash/mflash_pack_layer.c +++ b/mflash/mflash_pack_layer.c @@ -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: diff --git a/mflash/mflash_types.h b/mflash/mflash_types.h index b66f6ef..d85a28a 100644 --- a/mflash/mflash_types.h +++ b/mflash/mflash_types.h @@ -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, diff --git a/mtcr_ul/mtcr_ul.c b/mtcr_ul/mtcr_ul.c index cfacc7d..9c00ffe 100644 --- a/mtcr_ul/mtcr_ul.c +++ b/mtcr_ul/mtcr_ul.c @@ -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){ diff --git a/mtcr_ul/mtcr_ul_icmd_cif.c b/mtcr_ul/mtcr_ul_icmd_cif.c index a9b93e2..94c85bc 100644 --- a/mtcr_ul/mtcr_ul_icmd_cif.c +++ b/mtcr_ul/mtcr_ul_icmd_cif.c @@ -20,6 +20,14 @@ #include #include "mtcr_icmd_cif.h" +#ifdef __WIN__ +#include +#define getpid() _getpid() +#else +#include +#include +#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) { -- 2.46.0