/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
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; }
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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/* ****************************************************************************** @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; }