Fixed possible thread safety issues
authorPrasad Konnur <prasad.konnur@ti.com>
Thu, 10 Nov 2011 13:55:36 +0000 (19:25 +0530)
committerPrasad Konnur <prasad.konnur@ti.com>
Thu, 10 Nov 2011 13:55:36 +0000 (19:25 +0530)
packages/ti/sdo/edma3/drv/src/edma3_drv_adv.c
packages/ti/sdo/edma3/rm/src/edma3resmgr.c

index 7da2012ca8875400a39f4c3556b63c88578acc8d..58a1e2b6e2ffcb35f6a2986c6bb6ec2205300b82 100755 (executable)
@@ -1565,6 +1565,7 @@ EDMA3_DRV_Result EDMA3_DRV_setCCRegister (EDMA3_DRV_Handle hEdma,
                     uint32_t regOffset,
                     uint32_t newRegValue)
     {
+    uint32_t intState;
     EDMA3_DRV_Result result = EDMA3_DRV_SOK;
     EDMA3_DRV_Instance *drvInst = NULL;
     EDMA3_DRV_Object *drvObject = NULL;
@@ -1610,11 +1611,18 @@ EDMA3_DRV_Result EDMA3_DRV_setCCRegister (EDMA3_DRV_Handle hEdma,
 
                 if (EDMA3_DRV_SOK == result)
                     {
-                    /* Semaphore taken successfully, modify the registers. */
+                                       /* Semaphore taken successfully, modify the registers. */
+                    edma3OsProtectEntry (drvObject->phyCtrllerInstId,
+                                                                       EDMA3_OS_PROTECT_INTERRUPT,
+                                                                       &intState);
+                    /* Global interrupts disabled, modify the registers. */
                     regPhyAddr = (uint32_t)(drvObject->gblCfgParams.globalRegs) + regOffset;
 
                     *(uint32_t *)regPhyAddr = newRegValue;
 
+                    edma3OsProtectExit (drvObject->phyCtrllerInstId,
+                                                                       EDMA3_OS_PROTECT_INTERRUPT,
+                                                                       intState);
                     /* Return the semaphore back */
                     result = edma3OsSemGive(drvInst->drvSemHandle);
                     }
index eff554b8fbf7d48e1de89bfc9cc5870e0a902040..bebf9f9e03c8a8dba0ad08514e1749fd8ef68a24 100755 (executable)
@@ -1627,6 +1627,7 @@ EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
     EDMA3_RM_Instance *rmInstance = NULL;
     EDMA3_RM_Obj *rmObj = NULL;
     EDMA3_RM_Result result = EDMA3_RM_SOK;
+    EDMA3_RM_Result semResult = EDMA3_RM_SOK;
     uint32_t resId;
     uint32_t resIdSet = 0x0;
     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
@@ -1667,11 +1668,14 @@ EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
 
             resIdSet = 1u << (resId%32u);
 
-            edma3OsProtectEntry (rmObj->phyCtrllerInstId,
-                                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                                               &intState);
+           /**
+             * Take the instance specific semaphore, to prevent simultaneous
+             * access to the shared resources.
+             */
+           semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
+                                   EDMA3_OSSEM_NO_TIMEOUT);
 
-            if (EDMA3_RM_SOK == result)
+            if (EDMA3_RM_SOK == semResult)
                 {
                 switch (resObj->type)
                     {
@@ -1889,15 +1893,26 @@ EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
                         result = EDMA3_RM_E_INVALID_PARAM;
                         break;
                     }
-
+                semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
                 }
-
-            edma3OsProtectExit (rmObj->phyCtrllerInstId,
-                                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                                               intState);
             }
         }
 
+        /**
+         * Check the Free Resource Result 'result' first. If Free Resource
+         * has resulted in an error, return it (having more priority than
+         * semResult.
+         * Else, return semResult.
+         */
+         if (EDMA3_RM_SOK == result)
+            {
+            /**
+            * Free Resource successful, return semResult for returning
+            * semaphore.
+            */
+            result = semResult;
+        }
+
 #ifdef EDMA3_INSTRUMENTATION_ENABLED
     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
@@ -3979,6 +3994,7 @@ EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
                     uint32_t regOffset,
                     uint32_t newRegValue)
     {
+    uint32_t intState;
     EDMA3_RM_Result result = EDMA3_RM_SOK;
     EDMA3_RM_Instance *rmInstance = NULL;
     EDMA3_RM_Obj *rmObj = NULL;
@@ -4026,9 +4042,16 @@ EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
                 if (EDMA3_RM_SOK == result)
                     {
                     /* Semaphore taken successfully, modify the registers. */
+                    edma3OsProtectEntry (rmObj->phyCtrllerInstId,
+                                                                       EDMA3_OS_PROTECT_INTERRUPT,
+                                                                       &intState);
+                    /* Global interrupts disabled, modify the registers. */
                     regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
 
                     *(uint32_t *)regPhyAddr = newRegValue;
+                    edma3OsProtectExit (rmObj->phyCtrllerInstId,
+                                                                       EDMA3_OS_PROTECT_INTERRUPT,
+                                                                       intState);
 
                     /* Return the semaphore back */
                     result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
@@ -6033,7 +6056,6 @@ static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId)
 /** Initialization of the Shadow region registers of the EDMA3 Controller */
 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
     {
-    uint32_t  intState = 0u;
     volatile EDMA3_CCRL_Regs *ptrEdmaccRegs             = NULL;
     volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs   = NULL;
     uint32_t phyCtrllerInstId;
@@ -6088,23 +6110,11 @@ static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
             */
 
             /* 1. Dma Channel (and TCC) <-> Region */
-            edma3OsProtectEntry (phyCtrllerInstId,
-                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                               &intState);
             ptrEdmaccRegs->DRA[regionId].DRAE = 0u;
             ptrEdmaccRegs->DRA[regionId].DRAEH = 0u;
-            edma3OsProtectExit (phyCtrllerInstId,
-                                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                                               intState);
 
             /* 2. Qdma Channel <-> Region */
-            edma3OsProtectEntry (phyCtrllerInstId,
-                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                               &intState);
             ptrEdmaccRegs->QRAE[regionId] = 0u;
-            edma3OsProtectExit (phyCtrllerInstId,
-                                                               EDMA3_OS_PROTECT_INTERRUPT,
-                                                               intState);
             }
         }