Beispiel #1
0
/*!
******************************************************************************

 @Function                POOL_PoolCreate

******************************************************************************/
IMG_RESULT POOL_PoolCreate(
    IMG_HANDLE *  phPoolHandle
)
{
    POOL_sResPool *  psResPool;
    IMG_UINT32       ui32Result;

    IMG_ASSERT(gInitialised);

    /* Allocate a pool structure...*/
    psResPool = IMG_MALLOC(sizeof(*psResPool));
    IMG_ASSERT(psResPool != IMG_NULL);
    if (psResPool == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    IMG_MEMSET(psResPool, 0, sizeof(*psResPool));

    /* Initialise the pool info...*/
    LST_init(&psResPool->sFreeResList);
    LST_init(&psResPool->sActResList);

    /* Create mutex...*/
    ui32Result = SYSOSKM_CreateMutex(&psResPool->hMutexHandle);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_create_mutex;
    }

    /* Create context for the Id generator...*/
    ui32Result = IDGEN_CreateContext(POOL_IDGEN_MAX_ID, POOL_IDGEN_BLOCK_SIZE,IMG_FALSE, &psResPool->hIdGenHandle);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_create_context;
    }

    /* Disable interrupts.  */
    SYSOSKM_DisableInt();

    /* Add to list of pools...*/
    LST_add(&gsPoolList, psResPool);

    /* Enable interrupts.  */
    SYSOSKM_EnableInt();

    /* Return handle to pool...*/
    *phPoolHandle = psResPool;

    return IMG_SUCCESS;

    /* Error handling. */
error_create_context:
    SYSOSKM_DestroyMutex(psResPool->hMutexHandle);
error_create_mutex:
    IMG_FREE(psResPool);

    return ui32Result;
}
/*!
******************************************************************************

 @Function              VDECDDUTILS_CreateStrUnit

 @Description           this function allocate a structure for a complete data unit

******************************************************************************/
IMG_RESULT VDECDDUTILS_CreateStrUnit(
    VDECDD_sStrUnit    ** ppsStrUnit,
    LST_T               * sBSList
)
{
    VDECDD_sStrUnit    * psStrUnit;
    BSPP_sBitStrSeg  * psBitStrSeg;

    VDEC_MALLOC(psStrUnit);
    IMG_ASSERT(psStrUnit != IMG_NULL);
    if (psStrUnit == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    VDEC_BZERO(psStrUnit);
    if (sBSList != IMG_NULL)
    {
        // copy BS list to this list
        LST_init(&psStrUnit->sBitStrSegList);
        for ( psBitStrSeg = LST_first( sBSList); psBitStrSeg != NULL;   psBitStrSeg = LST_first(sBSList) )
        {
            psBitStrSeg = LST_removeHead(sBSList);
            LST_add(&psStrUnit->sBitStrSegList,psBitStrSeg);
        }
    }

    *ppsStrUnit = psStrUnit;

    return IMG_SUCCESS;
}
/*!
******************************************************************************

 @Function				SYSDEVU_RegisterDevices

******************************************************************************/
IMG_RESULT SYSDEVU_RegisterDevice(
	SYSDEVU_sInfo *psInfo
)
{
	IMG_UINT32			ui32Result;

	IMG_ASSERT(gSysDevInitialised);
	/* Initialise parts of the device info structure...*/
	psInfo->bDevLocated	= IMG_FALSE;
	psInfo->pvLocParam = IMG_NULL;

	SYSOSKM_LockMutex(hNextDeviceIdMutex);
	psInfo->ui32DeviceId = gui32NextDeviceId;
	gui32NextDeviceId += 1;
	SYSOSKM_UnlockMutex(hNextDeviceIdMutex);

	/* Register the device with the device manager...*/
	ui32Result = DMANKM_RegisterDevice(psInfo->sDevInfo.pszDeviceName, psInfo->sDevInfo.pfnDevRegister);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS)
	{
		return ui32Result;
	}

	/* Initialise the devices...*/
	LST_add(&gsDevList, psInfo);
	gui32NoDevices++;

	/* Return success...*/
	return IMG_SUCCESS;
}
Beispiel #4
0
/*!
******************************************************************************

 @Function                POOL_PoolSetFreeCallback

******************************************************************************/
IMG_RESULT POOL_PoolSetFreeCallback(
    IMG_HANDLE    hPoolHandle,
    POOL_pfnFree  pfnFree
)
{
    POOL_sResPool *   psResPool = hPoolHandle;
    POOL_sResource *  psResource;
    IMG_UINT32              ui32Result;

    IMG_ASSERT(gInitialised);
    IMG_ASSERT(psResPool != IMG_NULL);

    if (!gInitialised ||
        psResPool == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error_nolock;
    }

    /* Lock the pool...*/
    SYSOSKM_LockMutex(psResPool->hMutexHandle);

    psResPool->pfnFree = pfnFree;

    /* If free callback set...*/
    if (psResPool->pfnFree != IMG_NULL)
    {
        /* Move resources from free to active list...*/
        psResource = (POOL_sResource *)LST_removeHead(&psResPool->sFreeResList);
        while (psResource != IMG_NULL)
        {
            /* Add to active list...*/
            LST_add(&psResPool->sActResList, psResource);
            psResource->ui32RefCnt++;

            /* Unlock the pool...*/
            SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

            /* Call the free callback...*/
            psResPool->pfnFree(psResource->ui32ResId, psResource->pvParam);

            /* Lock the pool...*/
            SYSOSKM_LockMutex(psResPool->hMutexHandle);

            /* Get next free resource...*/
            psResource = (POOL_sResource *)LST_removeHead(&psResPool->sFreeResList);
        }
    }

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

    /* Return IMG_SUCCESS...*/
    return IMG_SUCCESS;

error_nolock:
    return ui32Result;
}
Beispiel #5
0
void quantile_update(LST lst,Quantile q,int pos,int read_cnt)
	{ int diff; 
	  COUNT_LST_NODE head, tail;
	  head = lst->cnt_lst->head;
	  tail = lst->cnt_lst->tail;

	  //printf("\nold read count = %d\t new read count = %d\n",lst->pos_lst->tail->read_cnt,read_cnt);
	  //printf("old quantile: %d\n",q->cnt_node->num_reads);
	  //printf("before deletion: q->k = %d\n",q->k);
	  /*delete the old genomic position (slide the window by 1 to the right, first step)*/
	  if(lst->pos_lst->tail->read_cnt == q->cnt_node->num_reads)
		{ if(q->cnt_node->num_pos == 1)
			{ if(head == tail)
				{ q->cnt_node=NULL;q->k=0;}
			  else if(q->cnt_node==head)
				{ q->cnt_node = q->cnt_node->next; q->k -= q->cnt_node->num_pos;}
			  else {q->cnt_node = q->cnt_node->pre;}
			  //printf("yes, there is only one in this class\n");
			}
		  delete_CNT(lst->cnt_lst,lst->pos_lst->tail->cnt_node);
		  del_tail_POS(lst->pos_lst);
		  //printf("Yes, equal\n");
		}
	  else 	{ diff = (lst->pos_lst->tail->read_cnt >= q->cnt_node->num_reads)? 0:-1;
		  q->k += diff;

		  delete_CNT(lst->cnt_lst,lst->pos_lst->tail->cnt_node);
                  del_tail_POS(lst->pos_lst);
		  //printf("No, unequal, diff=%d\n",diff);
		}
	  //printf("updated quantile: %d\n",q->cnt_node->num_reads);
	  //printf("before insertion: q->k = %d\n",q->k);


	  /*insert the new genomic postion (slide the window by 1 to the right, second step)*/
	  LST_add(lst,pos,read_cnt);

	  //printf("q->w*q->p is %g\n",q->w*q->p);
	  if(q->cnt_node==NULL)
		{ q->cnt_node = lst->cnt_lst->head;}
	  else
		{ diff = (read_cnt >= q->cnt_node->num_reads) ? 0 : 1;
		  q->k += diff;
		  if(((double)q->k+q->cnt_node->num_pos) - q->w*q->p < -1e-20) /*In case of q->k+q->cnt_node->num_pos < q->w*q->p*/
			{ q->k += q->cnt_node->num_pos;
			  q->cnt_node = q->cnt_node->pre; 
			}
		  else if(((double)q->k) - q->w*q->p > -1e-20 && q->k!=0) /*In case of q->k >= q->w*q->p*/
			{ q->cnt_node = q->cnt_node->next;
			  q->k -= q->cnt_node->num_pos;
			}
		}
	  //printf("new quantile: %d\n",q->cnt_node->num_reads);
	  //printf("after insertion: q->k = %d\n\n",q->k);

	  return;
	}
/*!
******************************************************************************

 @Function      perflog_WriteFile

 @Description

 Writes to the file.

 @Input    pFileHandler : file where data will be written

 @Input    uiMsg        : performance data

 @Return    IMG_SUCCESS in case when data has been written successfully,
            error code otherwise

******************************************************************************/
static IMG_RESULT perflog_WriteFile(perflog_FileHandler *pFileHandler, IMG_UINT64 uiMsg)
{
    perflog_Buffer  *psBuffer;

    if(pFileHandler == IMG_NULL)
    {
        REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR,
                "Performance logger cannot clean file: invalid parameters");
        return IMG_ERROR_INVALID_PARAMETERS;
    }

    SYSOSKM_LockMutex(pFileHandler->hMutexHandle);

    //search for buffer that has place to store perf data
    psBuffer = LST_first(&pFileHandler->sBufferList);
    while(psBuffer)
    {
        if(psBuffer->stIter < psBuffer->stBufferSize)
        {
            break;
        }
        psBuffer = LST_next(psBuffer);
    }

    //new buffer is needed
    if(psBuffer == IMG_NULL)
    {
        IMG_RESULT result;

        //create new buffer
        if( (result = perflog_CreateBuffer(&psBuffer, ONE_BUFFER_SIZE)) != IMG_SUCCESS )
        {
            SYSOSKM_UnlockMutex(pFileHandler->hMutexHandle);
            REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR,
                "Performance logger cannot allocate buffers");
            return result;
        }

        //add buffer to a list
        LST_add(&pFileHandler->sBufferList, psBuffer);
    }

    //write data
    psBuffer->pui64Buffer[(psBuffer->stIter)++] = uiMsg;

    SYSOSKM_UnlockMutex(pFileHandler->hMutexHandle);

    return IMG_SUCCESS;
}
Beispiel #7
0
void lst_initialize(int *bin, int nbins, LST lst, int win_size)
        { int i;

          if(lst==NULL)
                { printf("Error in \"lst_initialize\": one of the linked list not initialized.\n");
                  exit(1);
                }
          lst->cnt_lst->w = win_size;

          i = 0;
          while(i<nbins&&i<win_size)
                { LST_add(lst,bin[2*i],bin[2*i+1]);
                  i++;
                }
          if(i<win_size) lst->cnt_lst->w = i;

          return;
        }
Beispiel #8
0
/*!
******************************************************************************

 @Function                POOL_ResAlloc

******************************************************************************/
IMG_RESULT POOL_ResAlloc(
    IMG_HANDLE  hPoolHandle,
    IMG_HANDLE  hPoolResHandle
)
{
    POOL_sResPool *   psResPool  = hPoolHandle;
    POOL_sResource *  psResource = hPoolResHandle;
    IMG_UINT32              ui32Result;

    IMG_ASSERT(gInitialised);
    IMG_ASSERT(psResPool != IMG_NULL);
    IMG_ASSERT(hPoolResHandle != IMG_NULL);

    if (!gInitialised ||
        psResPool == IMG_NULL ||
        hPoolResHandle == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error_nolock;
    }

    /* Lock the pool...*/
    SYSOSKM_LockMutex(psResPool->hMutexHandle);

    /* Remove resource from free list...*/
    LST_remove(&psResPool->sFreeResList, psResource);

    /* Add to active list...*/
    LST_add(&psResPool->sActResList, psResource);
    psResource->ui32RefCnt++;

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

    /* Return IMG_SUCCESS...*/
    return IMG_SUCCESS;

error_nolock:
    return ui32Result;
}
/*!
******************************************************************************

 @Function              VDECDDUTILS_CreateStrUnitOld

 @Description           this function allocate a structure for a complete data unit


******************************************************************************/
IMG_RESULT VDECDDUTILS_CreateStrUnitOld(
    VDECDD_sStrUnit    ** ppsStrUnit,
    BSPP_sSequHdrInfo   * psSeqInfo,
    BSPP_sPictHdrInfo   * psPicInfo,
    LST_T               * sBSList
)
{
    VDECDD_sStrUnit    * psStrUnit;
    BSPP_sBitStrSeg  * psBitStrSeg;

    VDEC_MALLOC(psStrUnit);
    IMG_ASSERT(psStrUnit != IMG_NULL);
    if (psStrUnit == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    VDEC_BZERO(psStrUnit);
    if (sBSList != IMG_NULL)
    {
        // copy BS list to this list
        LST_init(&psStrUnit->sBitStrSegList);
        for ( psBitStrSeg = LST_first( sBSList); psBitStrSeg != NULL;   psBitStrSeg = LST_first(sBSList) )
        {
            psBitStrSeg = LST_removeHead(sBSList);
            LST_add(&psStrUnit->sBitStrSegList,psBitStrSeg);
        }

    }
    if(psSeqInfo !=IMG_NULL)
    {
        psStrUnit->psSequHdrInfo = psSeqInfo;
        psStrUnit->psSequHdrInfo->ui32RefCount = 1;
    }
    psStrUnit->psPictHdrInfo = psPicInfo;
    *ppsStrUnit = psStrUnit;

    return IMG_SUCCESS;
}
Beispiel #10
0
/*!
******************************************************************************

 @Function                POOL_ResRegister

******************************************************************************/
IMG_RESULT POOL_ResRegister(
    IMG_HANDLE          hPoolHandle,
    POOL_pfnDestructor  pfnDestructor,
    IMG_VOID *          pvParam,
    IMG_UINT32          ui32SizevParam,
    IMG_BOOL            bAlloc,
    IMG_UINT32 *        pui32ResId,
    IMG_HANDLE *        phPoolResHandle
)
{
    POOL_sResPool *   psResPool = hPoolHandle;
    POOL_sResource *  psResource;
    IMG_UINT32        ui32Result;

    IMG_ASSERT(gInitialised);
    IMG_ASSERT(psResPool != IMG_NULL);

    if (!gInitialised ||
        psResPool == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error_nolock;
    }

    /* Allocate a resource structure...*/
    psResource = IMG_MALLOC(sizeof(*psResource));
    IMG_ASSERT(psResource != IMG_NULL);
    if (psResource == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    IMG_MEMSET(psResource, 0, sizeof(*psResource));

    /* Setup the resource...*/
    psResource->pfnDestructor  = pfnDestructor;
    psResource->pvParam        = pvParam;
    psResource->ui32SizevParam = ui32SizevParam;
    psResource->psResPool      = psResPool;
    LST_init(&psResource->sCloneResList);

    /* Lock the pool...*/
    SYSOSKM_LockMutex(psResPool->hMutexHandle);

    /* Set resource id...*/
    ui32Result = IDGEN_AllocId(psResPool->hIdGenHandle, (IMG_HANDLE)psResource, &psResource->ui32ResId);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        IMG_FREE(psResource);
        /* Unlock the pool...*/
        SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

        return ui32Result;
    }

    /* If allocated or free callback not set...*/
    if ( (bAlloc) || (psResPool->pfnFree != IMG_NULL) )
    {
        /* Add to active list...*/
        LST_add(&psResPool->sActResList, psResource);
        psResource->ui32RefCnt++;
    }
    else
    {
        /* Add to free list...*/
        LST_add(&psResPool->sFreeResList, psResource);
    }

    /* Return the resource id...*/
    if (pui32ResId != IMG_NULL)
    {
        *pui32ResId = psResource->ui32ResId;
    }

    /* Return the handle to the resource...*/
    if (phPoolResHandle != IMG_NULL)
    {
        *phPoolResHandle = psResource;
    }

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);


    /* If free callback set...*/
    if (psResPool->pfnFree != IMG_NULL)
    {
        /* Call the free callback...*/
        psResPool->pfnFree(psResource->ui32ResId, psResource->pvParam);
    }

    /* Return IMG_SUCCESS...*/
    return IMG_SUCCESS;

error_nolock:
    return ui32Result;
}
/*!
 ******************************************************************************

 @Function				DMANKM_RegisterDevice

 ******************************************************************************/
IMG_RESULT DMANKM_RegisterDevice(IMG_CHAR * pszDeviceName,
		DMANKM_pfnDevRegister pfnDevRegister) 
{
	DMANKM_sDevContext * psDevContext;
	IMG_UINT32 ui32Result;

	/* If the device context list is not initialised...*/
	if (!gbDevListInitialised) {
		/* Initialise the device context list...*/
		LST_init(&gsDevList);

		gbDevListInitialised = IMG_TRUE;
	}

	/* Locate the device - ensure it's not registered twice...*/
	ui32Result = DMANKM_LocateDevice(pszDeviceName,
			(IMG_HANDLE *) &psDevContext);
	if (ui32Result != IMG_ERROR_DEVICE_NOT_FOUND) {
        IMG_ASSERT(ui32Result == IMG_ERROR_DEVICE_NOT_FOUND);
		return IMG_ERROR_GENERIC_FAILURE;
	}

	/* Allocate a device context structure...*/
	psDevContext = IMG_MALLOC(sizeof(*psDevContext));
	if (psDevContext == IMG_NULL ) 
    {
        IMG_ASSERT(psDevContext != IMG_NULL);
		return IMG_ERROR_OUT_OF_MEMORY;
	}

	IMG_MEMSET(psDevContext, 0, sizeof(*psDevContext));

	/* Setup the device context...*/
	psDevContext->ui32DeviceId = gui32NextDeviceID;
	gui32NextDeviceID++;
	psDevContext->pszDeviceName = IMG_STRDUP(pszDeviceName);
	if (psDevContext->pszDeviceName == IMG_NULL ) 
    {
        IMG_ASSERT(psDevContext->pszDeviceName != IMG_NULL);
		ui32Result = IMG_ERROR_OUT_OF_MEMORY;
		goto error_dev_name;
	}
	psDevContext->pfnDevRegister = pfnDevRegister;
	psDevContext->ui8ApmPpmFlags = 0;
	ui32Result = SYSOSKM_CreateMutex(&psDevContext->hMutexHandle);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_create_mutex;
	}
	LST_init(&psDevContext->sConnList);

	/* Disable interrupts...*/
	SYSOSKM_DisableInt();

	/* Add device to list...*/
	LST_add(&gsDevList, psDevContext);

	/* Re-enable interrupts...*/
	SYSOSKM_EnableInt();

	/* If initialised...*/
	if (gDmanKmInitialised) {
		/* Call device registration function...*/
		ui32Result = psDevContext->pfnDevRegister(&psDevContext->sDevRegister);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_dev_register;
		}

		/* Set default if required...*/
		if (psDevContext->sDevRegister.ui32ConnFlags == 0) {
			psDevContext->sDevRegister.ui32ConnFlags = DMAN_CFLAG_EXCLUSIVE;
		}
	}

	/* Return success...*/
	return IMG_SUCCESS;

	/* Error handling. */
	error_dev_register: SYSOSKM_DisableInt();
	LST_remove(&gsDevList, psDevContext);
	SYSOSKM_EnableInt();
	SYSOSKM_DestroyMutex(psDevContext->hMutexHandle);
	error_create_mutex:
	IMG_FREE(psDevContext->pszDeviceName);
	error_dev_name:
	IMG_FREE(psDevContext);

	return ui32Result;
}
/*!
 ******************************************************************************

 @Function				DMANKM_OpenDevice

 ******************************************************************************/
IMG_RESULT DMANKM_OpenDevice(IMG_HANDLE hDevHandle, DMAN_eOpenMode eOpenMode,
		IMG_HANDLE * phConnHandle, IMG_UINT32 * pui32ConnId) 
{
	DMANKM_sDevContext * psDevContext = (DMANKM_sDevContext *) hDevHandle;
	DMANKM_sConnContext * psConnContext;
	DMANKM_sConnContext * psInitConnContext = IMG_NULL;
	IMG_UINT32 ui32Result;
	IMG_HANDLE hProcessId;

	/* Check mode. */
	if ((eOpenMode != DMAN_OMODE_EXCLUSIVE)
			&& (eOpenMode != DMAN_OMODE_SHARED)) {
		IMG_ASSERT(IMG_FALSE);
		return IMG_ERROR_INVALID_PARAMETERS;
	}

	/* Loop over the device connections to see if this process already has a connection...*/
	hProcessId = SYSOSKM_GetProcessId();
	psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList);
	while (psConnContext != IMG_NULL ) {
		/* If process already has a connection. */
		if (psConnContext->hProcessId == hProcessId) {
			/* Update the open count...*/
			psConnContext->ui32OpenCnt++;

			/* Return the connection handle and/or id...*/
			if (phConnHandle != IMG_NULL ) {
				*phConnHandle = psConnContext;
			}
			if (pui32ConnId != IMG_NULL ) {
				*pui32ConnId = psConnContext->ui32ConnId;
			}

			/* Return success...*/
			return IMG_SUCCESS;
		}

		/* Look at next connection. */
		psConnContext = (DMANKM_sConnContext *) LST_next(psConnContext);
	}

	/* See if we have a connection exclusive access required or only exclusive access available. */
	psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList);
	if ((psConnContext != IMG_NULL )&&
	( (eOpenMode == DMAN_OMODE_EXCLUSIVE) ||
			(psConnContext->psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) )
	){
	IMG_ASSERT(IMG_FALSE);
	return IMG_ERROR_DEVICE_UNAVAILABLE;
}

	/* Allocate connection context...*/
	psConnContext = IMG_MALLOC(sizeof(*psConnContext));
	if (psConnContext == IMG_NULL ) 
    {
        IMG_ASSERT(psConnContext != IMG_NULL);
		return IMG_ERROR_OUT_OF_MEMORY;
	}
	IMG_MEMSET(psConnContext, 0, sizeof(*psConnContext));

	/* Initialise list of resource allocator...*/
	LST_init(&psConnContext->sAttachList);

	/* Setup connection context...*/
	psConnContext->psDevContext = psDevContext;
	psConnContext->ui32OpenCnt = 1;
	psConnContext->hProcessId = hProcessId;

	/* Update the count of connections...*/
	psDevContext->ui32ConnCnt++;

	/* If this is the first connection...*/
	if (psDevContext->ui32ConnCnt == 1) {
		/* Create resource bucket for connections and attachments...*/
		RMAN_Initialise();
		ui32Result = RMAN_CreateBucket(&psDevContext->hResBHandle);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_create_bucket;
		}
	}

	/* Add to list of connections...*/
	LST_add(&psDevContext->sConnList, psConnContext);
	ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle,
			DMAN_CONN_TYPE_ID, IMG_NULL, psConnContext,
			&psConnContext->hResHandle, &psConnContext->ui32ConnId);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_register_resource;
	}

	/* Register with the Process Manager in case the process dies...*/
	ui32Result = PMAN_Initialise();
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_pman_init;
	}
	PMAN_RegisterProcessLostCb(dmankm_fnProcessLostCb, psConnContext,
			&psConnContext->hProcLostCbHandle);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_pman_register_cb;
	}

	/* If this the first connection and initialise function...*/
	if ((psDevContext->ui32ConnCnt == 1)
			&& (psDevContext->sDevRegister.pfnDevInit != IMG_NULL )) {
		/* Allocate implicit connection context...*/
		psInitConnContext = IMG_MALLOC(sizeof(*psInitConnContext));
		if (psInitConnContext == IMG_NULL ) 
        {
            IMG_ASSERT(psInitConnContext != IMG_NULL);
			ui32Result = IMG_ERROR_OUT_OF_MEMORY;
			goto error_init_conn_ctx;
		}
		IMG_MEMSET(psInitConnContext, 0, sizeof(*psInitConnContext));

		/* Associated this connection with the device and process...*/
		psInitConnContext->psDevContext = psDevContext;
		psInitConnContext->ui32OpenCnt = 1;
		psInitConnContext->hProcessId = hProcessId;

		/* Mark this as the init connection...*/
		psInitConnContext->bInitConn = IMG_TRUE;

		/* Add implicit to list of connections...*/
		LST_add(&psDevContext->sConnList, psInitConnContext);
		ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle,
				DMAN_CONN_TYPE_ID, IMG_NULL, psInitConnContext,
				&psInitConnContext->hResHandle, &psInitConnContext->ui32ConnId);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_register_resource_init_ctx;
		}

		IMG_ASSERT(
				(psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) || (psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_SHARED));

		/* If it's not a pseudo device...  */
		if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE)
				== 0) {
			/* Open the device...*/
			ui32Result = SYSDEVU_OpenDevice(psDevContext->pszDeviceName,
					&psDevContext->hSysDevHandle);
			IMG_ASSERT(ui32Result == IMG_SUCCESS);
			if (ui32Result != IMG_SUCCESS) {
				goto error_open_device;
			}

			/* Power the device on.  */
			SYSDEVU_SetPowerState(psDevContext->hSysDevHandle,
					SYSOSKM_POWERSTATE_S0, IMG_FALSE);
		}

		ui32Result = psDevContext->sDevRegister.pfnDevInit(psDevContext,
				psInitConnContext, &psDevContext->pvDevInstanceData);
		if (ui32Result != IMG_SUCCESS) {
			REPORT(REPORT_MODULE_DMAN, REPORT_ERR, "dev init failed (%d)",
				ui32Result);
			goto error_dev_init;
		}

		/* If there is a Device Kernel mode HISR...*/
		if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) {
			IMG_ASSERT(psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL);
			ui32Result = SYSOSKM_CreateKmHisr(&dmankm_fnDevKmHisr, psDevContext,
					&psDevContext->hHISRHandle);
			IMG_ASSERT(ui32Result == IMG_SUCCESS);
			if (ui32Result != IMG_SUCCESS) {
				goto error_create_km_hisr;
			}
		}

		/* If there is a Device Kernel mode LISR...*/
		if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) {
			/* Register the LISR wrapper...*/
			SYSDEVU_RegisterDevKmLisr(psDevContext->hSysDevHandle,
					&dmankm_fnDevKmLisr, psDevContext);
		}
	}

	/* If connect/open function...*/
	if (psDevContext->sDevRegister.pfnDevConnect != IMG_NULL ) {
		ui32Result = psDevContext->sDevRegister.pfnDevConnect(psConnContext,
				psDevContext->pvDevInstanceData,
				&psConnContext->pvDevConnectionData);
		IMG_ASSERT(
				ui32Result == IMG_SUCCESS || ui32Result == IMG_ERROR_INTERRUPTED);
		if (ui32Result != IMG_SUCCESS && ui32Result != IMG_ERROR_INTERRUPTED) {
			goto error_dev_connect;
		}
	}

	/* Return the connection handle and/or id...*/
	if (phConnHandle != IMG_NULL ) {
		*phConnHandle = psConnContext;
	}
	if (pui32ConnId != IMG_NULL ) {
		*pui32ConnId = psConnContext->ui32ConnId;
	}

	/* Return success...*/
	return ui32Result;

	/* Error handling. */
error_dev_connect:
	/* If this not the first connection or there's no initialise function...*/
	if ((1 != psDevContext->ui32ConnCnt)
			|| (IMG_NULL == psDevContext->sDevRegister.pfnDevInit)) {
		/* ...skip de-initialisation of this part. */
		goto error_init_conn_ctx;
	}

	if (IMG_NULL != psDevContext->sDevRegister.pfnDevKmHisr) {
		SYSOSKM_DestroyKmHisr(psDevContext->hHISRHandle);
	}

error_create_km_hisr:
	if (IMG_NULL
			!= psDevContext->sDevRegister.pfnDevDeinit) {
		psDevContext->sDevRegister.pfnDevDeinit(psDevContext, psInitConnContext,
				psDevContext->pvDevInstanceData);
	}

error_dev_init:
	if ((psDevContext->sDevRegister.ui32DevFlags
			& DMAN_DFLAG_PSEUDO_DEVICE) == 0) {
		SYSDEVU_CloseDevice(psDevContext->hSysDevHandle);
	}

error_open_device:
	RMAN_FreeResource(psInitConnContext->hResHandle);

error_register_resource_init_ctx:
	LST_remove(&psDevContext->sConnList, psInitConnContext);
	IMG_FREE(psInitConnContext);

error_init_conn_ctx:
	PMAN_RemoveProcessLostCb(psConnContext->hProcLostCbHandle);
	/* release per-process resources in PMAN, allocated inside
	   PMAN_RegisterProcessLostCb. We have to use device disconnect,
	   although the device wasn't actually initialised, because no
	   other function is exposed by PMAN */
	PMAN_DevDisconnectComplete(hProcessId);

error_pman_register_cb:
error_pman_init:
	RMAN_FreeResource(psConnContext->hResHandle);

error_register_resource:
	LST_remove(&psDevContext->sConnList,psConnContext);
	if (1 == psDevContext->ui32ConnCnt) {
		RMAN_DestroyBucket(psDevContext->hResBHandle);
	}

error_create_bucket:
	psDevContext->ui32ConnCnt--;
	IMG_FREE(psConnContext);

	return ui32Result;
}
/*!
 ******************************************************************************

 @Function				DMANKM_AttachComponent

 ******************************************************************************/
IMG_RESULT DMANKM_AttachComponent(IMG_HANDLE hConnHandle,
		IMG_CHAR * pszCompName, DMANKM_pfnCompAttach pfnCompAttach,
		IMG_HANDLE * phAttachHandle, IMG_UINT32 * pui32AttachId) 
{
	DMANKM_sConnContext * psConnContext = (DMANKM_sConnContext *) hConnHandle;
	IMG_BOOL bFound;
	DMANKM_sAttachContext * psAttachContext;
	IMG_UINT32 ui32Result;

	IMG_ASSERT(gDmanKmInitialised);

	/* See if this component is already register with this connection...*/
	bFound = dman_LocateComponentKM(pszCompName, psConnContext,
			&psAttachContext);
	if (bFound) {
		/* Cross check name and attach function should be the same...*/
		IMG_ASSERT(psAttachContext->pfnCompAttach == pfnCompAttach);

		/* Return the attachment handle and/or id...*/
		if (phAttachHandle != IMG_NULL ) {
			*phAttachHandle = psAttachContext;
		}
		if (pui32AttachId != IMG_NULL ) {
			*pui32AttachId = psAttachContext->ui32AttachId;
		}

		return IMG_SUCCESS;
	}

	/* Allocate a attachment context structure...*/
	psAttachContext = IMG_MALLOC(sizeof(*psAttachContext));
	if (psAttachContext == IMG_NULL ) 
    {
        IMG_ASSERT(psAttachContext != IMG_NULL);
		return IMG_ERROR_OUT_OF_MEMORY;
	}
	IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext));

	/* Copy the component name etc...*/
	psAttachContext->pszCompName = IMG_STRDUP(pszCompName);
	if (psAttachContext->pszCompName == IMG_NULL ) 
    {
        IMG_ASSERT(psAttachContext->pszCompName != IMG_NULL);
		ui32Result = IMG_ERROR_OUT_OF_MEMORY;
		goto error_comp_name;
	}
	psAttachContext->pfnCompAttach = pfnCompAttach;
	psAttachContext->psConnContext = psConnContext;
	ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_create_bucket;
	}

	/* Add to the attachment component list...*/
	LST_add(&psConnContext->sAttachList, psAttachContext);
	ui32Result = RMAN_RegisterResource(psConnContext->psDevContext->hResBHandle,
			DMAN_ATTACH_TYPE_ID, IMG_NULL, psAttachContext,
			&psAttachContext->hResHandle, &psAttachContext->ui32AttachId);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_register_resource;
	}

	/* Call components attach function...*/
	ui32Result = pfnCompAttach(psAttachContext, &psAttachContext->sCompAttach);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_comp_attach;
	}

	/* If connect/open function...*/
	if (psAttachContext->sCompAttach.pfnCompConnect != IMG_NULL ) {
		ui32Result = psAttachContext->sCompAttach.pfnCompConnect(
				psAttachContext, &psAttachContext->pvCompAttachmentData);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_comp_connect;
		}
	}

	/* Return the attachment handle and/or id...*/
	if (phAttachHandle != IMG_NULL ) {
		*phAttachHandle = psAttachContext;
	}
	if (pui32AttachId != IMG_NULL ) {
		*pui32AttachId = psAttachContext->ui32AttachId;
	}

	/* Return success...*/
	return IMG_SUCCESS;

	/* Error handling. */
	error_comp_connect: error_comp_attach: RMAN_FreeResource(
			psAttachContext->hResHandle);
	error_register_resource: LST_remove(&psConnContext->sAttachList,
			psAttachContext);
	RMAN_DestroyBucket(psAttachContext->hResBHandle);
	error_create_bucket:
	IMG_FREE(psAttachContext->pszCompName);
	error_comp_name:
	IMG_FREE(psAttachContext);

	return ui32Result;
}
Beispiel #14
0
/*!
******************************************************************************

 @Function                POOL_ResClone

******************************************************************************/
IMG_RESULT POOL_ResClone(
    IMG_HANDLE    hPoolResHandle,
    IMG_HANDLE *  phClonePoolResHandle,
    IMG_VOID **   ppvParam
)
{
    POOL_sResource *  psResource = hPoolResHandle;
    POOL_sResPool *   psResPool;
    POOL_sResource *  psOrigResource = psResource;
    POOL_sResource *  psCloneResource;
    IMG_UINT32        ui32Result;

    IMG_ASSERT(gInitialised);
    IMG_ASSERT(psResource != IMG_NULL);

    if (!gInitialised ||
        psResource == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error_nolock;
    }

    /* Allocate a resource structure...*/
    psCloneResource = IMG_MALLOC(sizeof(*psCloneResource));
    IMG_ASSERT(psCloneResource != IMG_NULL);
    if (psCloneResource == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    IMG_MEMSET(psCloneResource, 0, sizeof(*psCloneResource));

    psResPool = psResource->psResPool;
    IMG_ASSERT(psResPool != IMG_NULL);
    if(psResPool == IMG_NULL)
    {
        return IMG_ERROR_FATAL;
    }

    /* Lock the pool...*/
    SYSOSKM_LockMutex(psResPool->hMutexHandle);

    /* Set resource id...*/
    ui32Result = IDGEN_AllocId(psResPool->hIdGenHandle, (IMG_HANDLE)psCloneResource, &psCloneResource->ui32ResId);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_alloc_id;
    }

    /* If this is a clone, set the original...*/
    if (psResource->bIsClone)
    {
        psOrigResource = psResource->psOrigResource;
    }
    IMG_ASSERT(psOrigResource->ui32RefCnt > 0);

    /* Setup the cloned resource...*/
    psCloneResource->bIsClone       = IMG_TRUE;
    psCloneResource->psResPool      = psResPool;
    psCloneResource->psOrigResource = psOrigResource;

    /* Add to clone list...*/
    LST_add(&psOrigResource->sCloneResList, psCloneResource);
    psOrigResource->ui32RefCnt++;

    /* If ppvParam is not IMG_NULL...*/
    if (ppvParam !=IMG_NULL)
    {
        /* If the size of the original vParam is 0...*/
        if (psOrigResource->ui32SizevParam == 0)
        {
            *ppvParam = IMG_NULL;
        }
        else
        {
            /* Allocate memory for a copy of the original vParam...*/
            *ppvParam = IMG_MALLOC(psOrigResource->ui32SizevParam);
            IMG_ASSERT(*ppvParam != IMG_NULL);
            if (*ppvParam == IMG_NULL)
            {
                ui32Result = IMG_ERROR_OUT_OF_MEMORY;
                goto error_copy_param;
            }
            IMG_MEMCPY(*ppvParam, psOrigResource->pvParam, psOrigResource->ui32SizevParam);
        }
    }

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

    /* Return the cloned resource...*/
    *phClonePoolResHandle = psCloneResource;

    /* Return IMG_SUCCESS...*/
    return IMG_SUCCESS;

    /* Error handling. */
error_copy_param:
    LST_remove(&psOrigResource->sCloneResList, psCloneResource);
    psOrigResource->ui32RefCnt--;
error_alloc_id:
    IMG_FREE(psCloneResource);

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

error_nolock:
    return ui32Result;
}
Beispiel #15
0
/*!
******************************************************************************

 @Function                POOL_ResFree

******************************************************************************/
IMG_RESULT POOL_ResFree(
    IMG_HANDLE  hPoolResHandle
)
{
    POOL_sResource *  psResource = hPoolResHandle;
    POOL_sResPool *   psResPool;
    POOL_sResource *  psOrigResource;
    IMG_UINT32        ui32Result;

    IMG_ASSERT(gInitialised);
    IMG_ASSERT(psResource != IMG_NULL);

    if (!gInitialised ||
        psResource == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error_nolock;
    }

    psResPool = psResource->psResPool;

    /* Lock the pool...*/
    SYSOSKM_LockMutex(psResPool->hMutexHandle);

    /* If this is a clone...*/
    if (psResource->bIsClone)
    {
        /* Get access to the original...*/
        psOrigResource = psResource->psOrigResource;
        IMG_ASSERT(psOrigResource != IMG_NULL);
        IMG_ASSERT(!psOrigResource->bIsClone);

        /* Remove from the clone list...*/
        LST_remove(&psOrigResource->sCloneResList, psResource);

        /* Free resource id...*/
        ui32Result = IDGEN_FreeId(psResPool->hIdGenHandle, psResource->ui32ResId);
        IMG_ASSERT(ui32Result == IMG_SUCCESS);
        if (ui32Result != IMG_SUCCESS)
        {
            /* Unlock the pool...*/
            SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

            return ui32Result;
        }

        /* If we created a copy of the resources pvParam then free it...*/
        if (psResource->pvParam != IMG_NULL)
        {
            IMG_FREE(psResource->pvParam );
        }
        /* Free the clone resource structure...*/
        IMG_FREE(psResource);

        /* Set resource to be "freed" to the original...*/
        psResource = psOrigResource;
    }

    /* Update the reference count...*/
    IMG_ASSERT(psResource->ui32RefCnt != 0);
    psResource->ui32RefCnt--;

    /* If there are still outstanding references...*/
    if (psResource->ui32RefCnt != 0)
    {
        /* Unlock the pool...*/
        SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

        /* Return IMG_SUCCESS...*/
        return IMG_SUCCESS;
    }

    /* Remove the resource from the active list...*/
    LST_remove(&psResPool->sActResList, psResource);

    /* If free callback set...*/
    if (psResPool->pfnFree != IMG_NULL)
    {
        /* Add to active list...*/
        LST_add(&psResPool->sActResList, psResource);
        psResource->ui32RefCnt++;
    }
    else
    {
        /* Add to free list...*/
        LST_add(&psResPool->sFreeResList, psResource);
    }

    /* Unlock the pool...*/
    SYSOSKM_UnlockMutex(psResPool->hMutexHandle);

    /* If free callback set...*/
    if (psResPool->pfnFree != IMG_NULL)
    {
        /* Call the free callback...*/
        psResPool->pfnFree(psResource->ui32ResId, psResource->pvParam);
    }

    /* Return IMG_SUCCESS...*/
    return IMG_SUCCESS;

error_nolock:
    return ui32Result;
}
Beispiel #16
0
/*
******************************************************************************

 @Function              MTXIO_ProcessMTXMsgs

******************************************************************************/
IMG_RESULT
MTXIO_ProcessMTXMsgs(
    MTXIO_sContext    * psContext,
    MSVDX_sMsgQueue   * psMsgQStatus
)
{
    IMG_UINT32 ui32ReadIdx, ui32WriteIdx, ui32BufferSize;
    IMG_UINT32 ui32FirstWord, ui32MessageSize;
    IMG_UINT32 * pui32FirstWord;
    VDECFW_eMessageID eMessageID;
    MSVDXIO_sHISRMsg  * psMessage;

    /* we can only read messages from the Completion buffer */
    MSVDX_eCommsArea eArea = MTXIO_AREA_COMPLETION;
#if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING)
    IMG_CHAR        szPdumpComment[100];
#endif

    // Initialise the output flags.
    IMG_ASSERT(psMsgQStatus);
    psMsgQStatus->bEmpty = IMG_FALSE;
    psMsgQStatus->bQueued = IMG_FALSE;
    IMG_ASSERT(!LST_empty(&psMsgQStatus->sFreeMsgList));
    IMG_ASSERT(LST_empty(&psMsgQStatus->sNewMsgList));

    ui32ReadIdx = mtxio_commsAreaGet( psContext, eArea, MTXIO_FIELD_RD_INDEX );
    ui32WriteIdx = mtxio_commsAreaGet( psContext, eArea, MTXIO_FIELD_WRT_INDEX );
    ui32BufferSize = mtxio_commsAreaGet( psContext, eArea, MTXIO_FIELD_SIZE );

    /* While there are messages to read and somewhere to put them. */
    while (ui32ReadIdx != ui32WriteIdx &&
           LST_first(&psMsgQStatus->sFreeMsgList))
    {
#if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING)
        /* reproduce message reading in a pdump script */
        MSVDXIO_PDUMPComment(psContext->hMsvdxIoCtx, psContext->asComms[eArea].eMemSpace,
            "MTXIO_ProcessMTXMsgs : Wait for COMPLETION area FW message");

        MSVDXIO_Poll(psContext->hMsvdxIoCtx,
            psContext->asComms[eArea].eMemSpace,
            gaui32VlrOffset[eArea] + psContext->asComms[eArea].ui32WrtIndexOffset,
            ui32ReadIdx,
            0xffffffff,
            MSVDXIO_POLL_NOT_EQUAL);
#endif

        /* read the first word of the message */
        mtxio_commsReadWords(psContext, 
                             eArea,
                             psContext->asComms[eArea].ui32BufOffset + (ui32ReadIdx<<2),
                             1, 
                             &ui32FirstWord, 
                             IMG_TRUE);

        /* get the message size in words and ID */
        pui32FirstWord = &ui32FirstWord;
        ui32MessageSize = (MEMIO_READ_FIELD(pui32FirstWord, V2_PADMSG_SIZE) + 3) / 4;
        eMessageID = MEMIO_READ_FIELD(pui32FirstWord, V2_PADMSG_MID);

        /* sanity check - message fits in buffer and does not go past write pointer */
        IMG_ASSERT( ui32MessageSize < ui32BufferSize );
        IMG_ASSERT( (ui32ReadIdx > ui32WriteIdx) || ((ui32ReadIdx + ui32MessageSize) <= ui32WriteIdx) );
        /* sanity check - message is of the MTX -> Host type */
        IMG_ASSERT( eMessageID >= VDECFW_MSGID_BE_PADDING );

#if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING)

        snprintf(szPdumpComment, 99, "MTXIO_ProcessMTXMsgs: %s message received", 
            eMessageID == VDECFW_MSGID_BE_PADDING ?  "PADDING" : 
            eMessageID == VDECFW_MSGID_PIC_DECODED ? "PIC DECODED" : 
            eMessageID == VDECFW_MSGID_PIC_CRCS ? "CRC" : 
            eMessageID == VDECFW_MSGID_PIC_PERFORMANCE ? "PERFORMANCE" : "UNKNOWN");
        szPdumpComment[99] = 0;

        MSVDXIO_PDUMPComment(psContext->hMsvdxIoCtx, psContext->asComms[eArea].eMemSpace,
            szPdumpComment);
#endif
        /* consume if the message is a padding message */
        if ( VDECFW_MSGID_BE_PADDING == eMessageID )
        {
            /* sanity check - message does infact pad to the end of the buffer */
            IMG_ASSERT( ui32ReadIdx > ui32WriteIdx );
            IMG_ASSERT( (ui32ReadIdx + ui32MessageSize) == ui32BufferSize );
            ui32ReadIdx = 0;
            mtxio_commsAreaSet( psContext, eArea, MTXIO_FIELD_RD_INDEX, ui32ReadIdx );
            continue;
        }

        psMessage = LST_removeHead(&psMsgQStatus->sFreeMsgList);
        IMG_ASSERT(psMessage);

        /* copy message into internal buffer and get new read index */
        ui32ReadIdx = mtxio_copyMessageData(psContext, 
                                            eArea, 
                                            ui32ReadIdx,
                                            psMsgQStatus->ui32WriteIdx,
                                            psMsgQStatus->ui32ReadIdx,
                                            ui32MessageSize, 
                                            ui32BufferSize,
                                            psMessage,
                                            psMsgQStatus->aui32MsgBuf);

        psMsgQStatus->ui32WriteIdx = psMessage->ui32NewRdIndex;

        /* Add the message to the HISR active list */
        LST_add(&psMsgQStatus->sNewMsgList, psMessage);

        /* update the read index */
        mtxio_commsAreaSet( psContext, eArea, MTXIO_FIELD_RD_INDEX, ui32ReadIdx );

        psMsgQStatus->bQueued = IMG_TRUE;

#if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING)
        MSVDXIO_PDUMPComment(psContext->hMsvdxIoCtx, psContext->asComms[eArea].eMemSpace,
            "MTXIO_ProcessMTXMsgs: FW message receive complete");
#endif
    }

    /* report success or otherwise */
    psMsgQStatus->bEmpty = ((ui32ReadIdx == ui32WriteIdx) ? IMG_TRUE: IMG_FALSE);

    return IMG_SUCCESS;
}
/*!
******************************************************************************

 @Function              RESOURCE_ListAdd

******************************************************************************/
IMG_RESULT
RESOURCE_ListAdd(
    LST_T *       psList,
    IMG_VOID *    pvItem,
    IMG_UINT32    ui32Id,
    IMG_UINT32 *  pui32RefCount
)
{
    RESOURCE_sListElem *  psListElem = IMG_NULL;
    IMG_BOOL bFound = IMG_FALSE;
    IMG_UINT32  ui32Result;

    /* Check input params. */
    IMG_ASSERT(IMG_NULL != psList);
    IMG_ASSERT(IMG_NULL != pvItem);

    if (psList == IMG_NULL ||
        pvItem == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error;
    }

    /* Decrement the reference count on the item
       to signal that the owner has relinquished it. */
    ui32Result = RESOURCE_ItemReturn(pui32RefCount);
    if (ui32Result != IMG_SUCCESS)
    {
        ui32Result = IMG_ERROR_UNEXPECTED_STATE;
        goto error;
    }

    /* Determine whether this buffer is already in the list. */
    psListElem = LST_first(psList);
    while (psListElem)
    {
        if (psListElem->pvItem == pvItem)
        {
            bFound = IMG_TRUE;
            break;
        }

        psListElem = LST_next(psListElem);
    }

    if (!bFound)
    {
        /* Allocate the image buffer list element structure. */
        VDEC_MALLOC(psListElem);
        if (IMG_NULL == psListElem)
        {
            REPORT(REPORT_MODULE_RESOURCE, REPORT_ERR,
                "Failed to allocate memory for RESOURCE list element");
            ui32Result = IMG_ERROR_OUT_OF_MEMORY;
            goto error;
        }
        VDEC_BZERO(psListElem);

        /* Setup the list element. */
        psListElem->pvItem = pvItem;
        psListElem->ui32Id = ui32Id;
        psListElem->pui32RefCount = pui32RefCount;

        /* Add the element to the list. */
        LST_add(psList, (IMG_VOID *)psListElem);
    }

    return IMG_SUCCESS;

error:
    return ui32Result;
}
/*!
******************************************************************************

 @Function              RESOURCE_ListReplace

******************************************************************************/
IMG_RESULT
RESOURCE_ListReplace(
    LST_T                 * psList,
    IMG_VOID              * pvItem,
    IMG_UINT32              ui32Id,
    IMG_UINT32            * pui32RefCount,
    RESOURCE_pfnFreeItem    pfnFreeItem,
    IMG_VOID              * pvFreeCbParam
)
{
    RESOURCE_sListElem    * psListElem = IMG_NULL;
    IMG_UINT32              ui32Result;

    /* Check input params. */
    IMG_ASSERT(IMG_NULL != psList);
    IMG_ASSERT(IMG_NULL != pvItem);
    if (psList == IMG_NULL ||
        pvItem == IMG_NULL)
    {
        ui32Result = IMG_ERROR_INVALID_PARAMETERS;
        goto error;
    }

    /* Determine whether this sequence header is already in the list. */
    psListElem = LST_first(psList);
    while (psListElem)
    {
        if (psListElem->ui32Id == ui32Id)
        {
            /* Free old version. */
            RESOURCE_ItemReturn(psListElem->pui32RefCount);
            if (*psListElem->pui32RefCount == 0)
            {
                if (pfnFreeItem)
                {
                    pfnFreeItem(psListElem->pvItem, pvFreeCbParam);
                }
                else
                {
                    IMG_FREE(psListElem->pvItem);
                }
                psListElem->pvItem = IMG_NULL;
            }

            LST_remove(psList, psListElem);
            break;
        }

        psListElem = LST_next(psListElem);
    }

    if (psListElem == IMG_NULL)
    {
        /* Allocate the sequence header list element structure. */
        VDEC_MALLOC(psListElem);
        if (IMG_NULL == psListElem)
        {
            REPORT(REPORT_MODULE_RESOURCE, REPORT_ERR,
                "Failed to allocate memory for RESOURCE list element");
            return IMG_ERROR_OUT_OF_MEMORY;
        }
    }
    VDEC_BZERO(psListElem);

    /* Setup the sequence header list element. */
    RESOURCE_ItemUse(pui32RefCount);

    psListElem->pvItem = pvItem;
    psListElem->ui32Id = ui32Id;
    psListElem->pui32RefCount = pui32RefCount;

    /* Add the sequence header list element to the sequence header list. */
    LST_add(psList, (IMG_VOID *)psListElem);

    return IMG_SUCCESS;

error:
    return ui32Result;
}