/*! ****************************************************************************** @Function RESOURCE_ListEmpty ******************************************************************************/ IMG_RESULT RESOURCE_ListEmpty( LST_T * psList, IMG_BOOL bReleaseItems, RESOURCE_pfnFreeItem pfnFreeItem, IMG_VOID * pvFreeCbParam ) { RESOURCE_sListElem * psListElem = IMG_NULL; IMG_UINT32 ui32Result; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); if (psList == IMG_NULL) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error; } /* Remove all the buffer list elements from the image buffer list. */ psListElem = LST_removeHead(psList); while (IMG_NULL != psListElem) { if (bReleaseItems) { RESOURCE_ItemRelease(psListElem->pui32RefCount); } else { /* Return and free. */ RESOURCE_ItemReturn(psListElem->pui32RefCount); if (psListElem->pui32RefCount == IMG_NULL || *psListElem->pui32RefCount == 0) { if (pfnFreeItem) { pfnFreeItem(psListElem->pvItem, pvFreeCbParam); } else { IMG_FREE(psListElem->pvItem); } psListElem->pvItem = IMG_NULL; } } /* Free the buffer list element. */ IMG_FREE(psListElem); psListElem = IMG_NULL; /* Get the next element from the list. */ psListElem = LST_removeHead(psList); } return IMG_SUCCESS; error: return ui32Result; }
/*! ******************************************************************************** @Function POOL_Delete @Description Delete an sObject sPool. All psObjects allocated from the sPool must be free'd with pool_free() before deleting the sObject sPool. @Input psPool : Object Pool pointer @Return IMG_RESULT : IMG_SUCCESS or an error code. ********************************************************************************/ IMG_RESULT POOL_Delete( struct sPool * const psPool ) { struct sBuffer * psBuffer = IMG_NULL; IMG_UINT32 ui32Result = IMG_ERROR_FATAL; IMG_ASSERT(IMG_NULL != psPool); if (IMG_NULL == psPool) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error; } psBuffer = psPool->psBuffers; while (IMG_NULL != psBuffer) { psBuffer = psBuffer->psNext; if(IMG_NULL != psPool->psBuffers) { IMG_FREE(psPool->psBuffers); } psPool->psBuffers = psBuffer; } IMG_FREE(psPool); ui32Result = IMG_SUCCESS; error: return ui32Result; }
/*! ****************************************************************************** @Function dmankm_DisconnectComps ******************************************************************************/ static IMG_RESULT dmankm_DisconnectComps(DMANKM_sConnContext * psConnContext) { DMANKM_sAttachContext * psAttachContext; IMG_UINT32 ui32Result; psAttachContext = (DMANKM_sAttachContext *) LST_first( &psConnContext->sAttachList); while (psAttachContext != IMG_NULL ) { /* If there is a disconnect function...*/ if (psAttachContext->sCompAttach.pfnCompDisconnect != IMG_NULL ) { /* Call it...*/ ui32Result = psAttachContext->sCompAttach.pfnCompDisconnect( psAttachContext, psAttachContext->pvCompAttachmentData); if (ui32Result != IMG_SUCCESS) { IMG_ASSERT(ui32Result == IMG_SUCCESS); return ui32Result; } } /* Remove, free the name and control block...*/ LST_remove(&psConnContext->sAttachList, psAttachContext); RMAN_DestroyBucket(psAttachContext->hResBHandle); RMAN_FreeResource(psAttachContext->hResHandle); IMG_FREE(psAttachContext->pszCompName); IMG_FREE(psAttachContext); psAttachContext = (DMANKM_sAttachContext *) LST_first( &psConnContext->sAttachList); } /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RMAN_CreateBucket ******************************************************************************/ IMG_RESULT RMAN_CreateBucket( IMG_HANDLE * phResBHandle ) { RMAN_sBucket * psBucket; IMG_UINT32 i; IMG_RESULT i32Result; IMG_ASSERT(gInitialised); /* Allocate a bucket structure...*/ psBucket = IMG_MALLOC(sizeof(*psBucket)); IMG_ASSERT(psBucket != IMG_NULL); if (psBucket == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psBucket, 0, sizeof(*psBucket)); /* Intialise the resource list...*/ DQ_init(&psBucket->sResList); /* The start allocating resource ids at the first...*/ i32Result = IDGEN_CreateContext(RMAN_MAX_ID, RMAN_ID_BLOCKSIZE, IMG_FALSE, &psBucket->hIdGenerator); if(i32Result != IMG_SUCCESS) { IMG_FREE(psBucket); IMG_ASSERT(!"failed to create IDGEN context"); return i32Result; } /* Locate free bucket index within the table...*/ SYSOSKM_DisableInt(); for (i=0; i<RMAN_CRESID_MAX_BUCKET_INDEX; i++) { if (gapsBucket[i] == IMG_NULL) { break; } } if (i >= RMAN_CRESID_MAX_BUCKET_INDEX) { SYSOSKM_EnableInt(); IDGEN_DestroyContext(psBucket->hIdGenerator); IMG_FREE(psBucket); IMG_ASSERT(!"No free buckets left"); return IMG_ERROR_GENERIC_FAILURE; } /* Allocate bucket index...*/ psBucket->ui32BucketIndex = i; gapsBucket[i] = psBucket; SYSOSKM_EnableInt(); /* Return the bucket handle...*/ *phResBHandle = psBucket; return IMG_SUCCESS; }
/*! ****************************************************************************** @Function DMANKM_UnRegisterDevice ******************************************************************************/ IMG_RESULT DMANKM_UnRegisterDevice(IMG_CHAR * pszDeviceName) { DMANKM_sDevContext *devContext; DMANKM_sConnContext *devConnection; IMG_RESULT ui32Result; devContext = (DMANKM_sDevContext *) LST_first(&gsDevList); while (devContext != IMG_NULL ) { if (!strcmp(devContext->pszDeviceName, pszDeviceName)) { devConnection = (DMANKM_sConnContext *) LST_first( &devContext->sConnList); while (devConnection != IMG_NULL ) { /* If this is the init connection....*/ if (devConnection->bInitConn) { devConnection = (DMANKM_sConnContext *) LST_next( &devContext->sConnList); } else { /* Lock the device...*/ DMANKM_LockDeviceContext(devContext); /* Call on to the kernel function...*/ ui32Result = DMANKM_CloseDevice(devContext, devConnection, DMAN_DCONN_ABORT); IMG_ASSERT(ui32Result == IMG_SUCCESS); // NOTE: We do not unlock the device as this will be done by // DMANKM_DevDisconnectComplete(). // /* Unlock the device...*/ // DMANKM_UnlockDeviceContext(hDevHandle); /* Move to next connection...*/ devConnection = (DMANKM_sConnContext *) LST_first( &devContext->sConnList); } } SYSOSKM_DestroyMutex(devContext->hMutexHandle); /* Remove entries in debug file system */ #ifdef IMG_KERNEL_MODULE //if (devContext->psDgRoot) { // debugfs_remove_recursive(devContext->psDgRoot); //} #endif LST_remove(&gsDevList, devContext); IMG_FREE(devContext->pszDeviceName); IMG_FREE(devContext); return IMG_SUCCESS; } devContext = LST_next(devContext); } return IMG_ERROR_GENERIC_FAILURE; }
/*! ****************************************************************************** @Function VDECDDUTILS_FreeStrUnit ******************************************************************************/ IMG_RESULT VDECDDUTILS_FreeStrUnit( VDECDD_sStrUnit * psStrUnit ) { BSPP_sBitStrSeg * psBitStrSeg; /* Loop over bit stream segments...*/ psBitStrSeg = (BSPP_sBitStrSeg *)LST_removeHead(&psStrUnit->sBitStrSegList); while (psBitStrSeg != IMG_NULL) { /* Free segment. */ IMG_FREE(psBitStrSeg); /* Get next segment. */ psBitStrSeg = (BSPP_sBitStrSeg *)LST_removeHead(&psStrUnit->sBitStrSegList); } /* Free the sequence header...*/ if (psStrUnit->psSequHdrInfo != IMG_NULL) { psStrUnit->psSequHdrInfo->ui32RefCount--; if (psStrUnit->psSequHdrInfo->ui32RefCount == 0) { IMG_FREE(psStrUnit->psSequHdrInfo); psStrUnit->psSequHdrInfo = IMG_NULL; } } /* Free the picture header... */ if (psStrUnit->psPictHdrInfo != IMG_NULL) { if (psStrUnit->psPictHdrInfo->sPictSgmData.pvData) { IMG_FREE(psStrUnit->psPictHdrInfo->sPictSgmData.pvData); psStrUnit->psPictHdrInfo->sPictSgmData.pvData = IMG_NULL; } IMG_FREE(psStrUnit->psPictHdrInfo); psStrUnit->psPictHdrInfo = IMG_NULL; } /* Free stream unit. */ IMG_FREE(psStrUnit); psStrUnit = IMG_NULL; /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function SECDEV_DeInitialise ******************************************************************************/ IMG_VOID SECDEV_DeInitialise(SECDEV_eMapArea eArea) { if (gbDevMapped) { #if defined (TARGET_FPGA) if(eArea == SECDEV_MAPAREA_REGISTER) { pciio_UnmapResources(1); } #ifdef SECURE_MEDIA_SUPPORT if(eArea == SECDEV_MAPAREA_MEMORY) { printk(KERN_DEBUG "Umapping secure memory\n"); pciio_UnmapResources(2); } if(gsPCIMem[1].pvKmAddr == IMG_NULL && gsPCIMem[2].pvKmAddr == IMG_NULL) { gbDevMapped = IMG_FALSE; } #else gbDevMapped = IMG_FALSE; #endif #elif defined (TARGET_CEDARVIEW) pciio_UnmapResources(0); gbDevMapped = IMG_FALSE; #endif } if (gpszDevName) { IMG_FREE(gpszDevName); gpszDevName = IMG_NULL; } }
/*! ****************************************************************************** @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 palloc_fnCompDisconnect ******************************************************************************/ static IMG_RESULT palloc_fnCompDisconnect ( IMG_HANDLE hAttachHandle, IMG_VOID * pvCompAttachmentData ) { PALLOC_sAttachContext * psAttachContext = pvCompAttachmentData; LOG_EVENT(PALLOC, PALLOC_COMPDISCONNECT, (LOG_FLAG_START), 0, 0); /* Destroy the bucket and it's resources...*/ RMAN_DestroyBucket(psAttachContext->hResBHandle); /* If we opened a device...*/ if (psAttachContext->hSysDevHandle != IMG_NULL) { SYSDEVKM_CloseDevice(psAttachContext->hSysDevHandle); } /* Free attachment context...*/ IMG_FREE(psAttachContext); LOG_EVENT(PALLOC, PALLOC_COMPDISCONNECT, (LOG_FLAG_END), 0, 0); /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RESOURCE_ListRemoveHead ******************************************************************************/ IMG_VOID * RESOURCE_ListRemoveHead( LST_T * psList ) { RESOURCE_sListElem * psListElem = IMG_NULL; IMG_VOID * pvItem = IMG_NULL; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); if (psList == IMG_NULL) { goto error; } /* Peek the head item of the list. */ psListElem = LST_removeHead(psList); if (psListElem) { pvItem = psListElem->pvItem; /* Free the list element. */ IMG_FREE(psListElem); psListElem = IMG_NULL; } error: return pvItem; }
/*! ****************************************************************************** @Function palloc_fnCompConnect ******************************************************************************/ static IMG_RESULT palloc_fnCompConnect ( IMG_HANDLE hAttachHandle, IMG_VOID ** ppvCompAttachmentData ) { PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32Result; IMG_CHAR * pszDeviceName; /* Allocate attachment context structure...*/ psAttachContext = IMG_MALLOC(sizeof(*psAttachContext)); IMG_ASSERT(psAttachContext != IMG_NULL); if (psAttachContext == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext)); /* Ensure the resource manager is initialised...*/ ui32Result = RMAN_Initialise(); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_rman_init; } /* Create a bucket for the resources...*/ ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_rman_bucket; } /* Get device information...*/ psAttachContext->hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); pszDeviceName = DMANKM_GetDeviceName(psAttachContext->hDevHandle); ui32Result = SYSDEVU_OpenDevice(pszDeviceName, &psAttachContext->hSysDevHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_sysdev_open; } /* Return attachment context...*/ *ppvCompAttachmentData = psAttachContext; /* Return success...*/ return IMG_SUCCESS; /* Error handling. */ error_sysdev_open: RMAN_DestroyBucket(psAttachContext->hResBHandle); error_rman_bucket: error_rman_init: IMG_FREE(psAttachContext); return ui32Result; }
/*! ****************************************************************************** @Function SECDEV_DeInitialise ******************************************************************************/ IMG_VOID SECDEV_DeInitialise(SECDEV_eMapArea eArea) { if (gpszDevName) { IMG_FREE(gpszDevName); gpszDevName = IMG_NULL; } }
/*! ****************************************************************************** @Function SYSMEMKM_Deinitialise ******************************************************************************/ static IMG_VOID Deinitialise( SYSMEM_Heap * heap ) { struct priv_params *priv = (struct priv_params *)heap->priv; /* If we have a page allocation array - free it...*/ gen_pool_destroy(priv->pool); IMG_FREE(priv); heap->priv = IMG_NULL; }
/*! ****************************************************************************** @Function palloc_fnFree ******************************************************************************/ static IMG_VOID palloc_fnFree( IMG_VOID * pvParam ) { PALLOC_sKmAlloc *psKmAlloc = (PALLOC_sKmAlloc *) pvParam; IMG_UINT numPages; LOG_EVENT(PALLOC, PALLOC_FREE, LOG_FLAG_START | LOG_FLAG_QUAL_ARG1, (IMG_UINT32) (IMG_UINTPTR) pvParam, 0); numPages = (psKmAlloc->sAllocInfo.ui32Size + SYS_MMU_PAGE_SIZE - 1)/SYS_MMU_PAGE_SIZE; switch (psKmAlloc->eBufType) { case PALLOC_BUFTYPE_PALLOCATED: /* If this is not a mapping only */ if (!psKmAlloc->sAllocInfo.bMappingOnly) { /* Free pages */ SYSMEMU_FreePages(psKmAlloc->hPagesHandle); } break; case PALLOC_BUFTYPE_USERALLOC: SYSOSKM_ReleaseCpuPAddrArray(((SYSMEMU_sPages *) psKmAlloc->hPagesHandle)->pvCpuKmAddr, psKmAlloc->hBufHandle, psKmAlloc->sAllocInfo.psSysPAddr, numPages); SYSMEMU_FreePages(psKmAlloc->hPagesHandle); break; case PALLOC_BUFTYPE_ANDROIDNATIVE: #if defined ANDROID_ION_BUFFERS palloc_ReleaseIONBuf(psKmAlloc->hBufHandle, NULL); SYSMEMU_FreePages(psKmAlloc->hPagesHandle); #elif defined ANDROID // Default gralloc: ashmem SYSOSKM_ReleaseCpuPAddrArray(((SYSMEMU_sPages *) psKmAlloc->hPagesHandle)->pvCpuKmAddr, psKmAlloc->hBufHandle, psKmAlloc->sAllocInfo.psSysPAddr, numPages); SYSMEMU_FreePages(psKmAlloc->hPagesHandle); #else IMG_ASSERT(!"palloc_fnFree wrong buffer type"); #endif break; default: IMG_ASSERT(!"palloc_fnFree wrong buffer type"); } IMG_BIGORSMALL_FREE(numPages * sizeof(IMG_SYS_PHYADDR), psKmAlloc->sAllocInfo.psSysPAddr); /* Free this structure */ IMG_FREE(psKmAlloc); LOG_EVENT(PALLOC, PALLOC_FREE, LOG_FLAG_END | LOG_FLAG_QUAL_ARG1, (IMG_UINT32) (IMG_UINTPTR) pvParam, 0); }
/*! ****************************************************************************** @Function RESOURCE_ListRemove ******************************************************************************/ IMG_RESULT RESOURCE_ListRemove( LST_T * psList, IMG_VOID * pvItem ) { 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; } /* Find the specified item in the list. */ psListElem = LST_first(psList); while (psListElem) { if (psListElem->pvItem == pvItem) { if (*psListElem->pui32RefCount != 0) { REPORT(REPORT_MODULE_RESOURCE, REPORT_WARNING, "Element removed from list whilst still in use"); } /* Remove the item from the list. */ LST_remove(psList, psListElem); /* Free the stream unit queue element. */ IMG_FREE(psListElem); psListElem = IMG_NULL; return IMG_SUCCESS; } psListElem = LST_next(psListElem); } DEBUG_REPORT(REPORT_MODULE_RESOURCE, "Item could not be located to remove from RESOURCE list"); return IMG_ERROR_COULD_NOT_OBTAIN_RESOURCE; error: return ui32Result; }
IMG_RESULT SYSMEMKM_AddCarveoutMemory( IMG_UINTPTR vstart, IMG_PHYSADDR pstart, IMG_UINT32 size, SYS_eMemPool * peMemPool ) { IMG_RESULT ui32Result; struct priv_params *prv; struct gen_pool *pool = gen_pool_create(12, -1); prv = (struct priv_params *)IMG_MALLOC(sizeof(*prv)); IMG_ASSERT(prv != IMG_NULL); if(IMG_NULL == prv) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_priv_alloc; } IMG_MEMSET((void *)prv, 0, sizeof(*prv)); IMG_ASSERT(pool != IMG_NULL); IMG_ASSERT(size != 0); IMG_ASSERT((vstart & (HOST_MMU_PAGE_SIZE-1)) == 0); gen_pool_add_virt(pool, (unsigned long)vstart, (unsigned long)pstart, size, -1); prv->pool = pool; prv->pstart = pstart; prv->size = size; prv->vstart = vstart; ui32Result = SYSMEMU_AddMemoryHeap(&carveout_ops, IMG_TRUE, (IMG_VOID *)prv, peMemPool); IMG_ASSERT(IMG_SUCCESS == ui32Result); if(IMG_SUCCESS != ui32Result) { goto error_heap_add; } return IMG_SUCCESS; error_heap_add: IMG_FREE(prv); error_priv_alloc: gen_pool_destroy(pool); return ui32Result; }
/*! ****************************************************************************** @Function MEMMAPPEDIO_DeInitialise ******************************************************************************/ IMG_VOID MEMMAPPEDIO_DeInitialise(MEMMAPPEDIO_eMapArea eArea) { if (gbDevMapped) { //iounmap(reg_base_addr); #if defined(SECURE_MEDIA_SUPPORT) && \ !defined(TARGET_ARM_CORTEX_A11) && !defined(TARGET_ARM_GOLDFISH) && \ !defined IMG_MEMALLOC_UNIFIED_VMALLOC iounmap(ram_base_addr); #endif gbDevMapped = IMG_FALSE; } if (gpszDevName) { IMG_FREE(gpszDevName); gpszDevName = IMG_NULL; } }
/*! ****************************************************************************** @Function SYSDEVKM_CloseDevice ******************************************************************************/ IMG_VOID SYSDEVKM_CloseDevice( IMG_HANDLE hSysDevHandle ) { SYSDEVKM_sDevice * psDevice = (SYSDEVKM_sDevice *)hSysDevHandle; IMG_ASSERT(hSysDevHandle != IMG_NULL); if (hSysDevHandle == IMG_NULL) { return; } IMG_FREE(psDevice); /* Update count...*/ SYSOSKM_DisableInt(); gsActiveOpenCnt--; SYSOSKM_EnableInt(); }
/*! ****************************************************************************** @Function free_device ******************************************************************************/ static IMG_VOID free_device(SYSDEVU_sInfo *psInfo) { if (IMG_TRUE == gbDevDetected) { platform_driver_unregister(&local_driver); gbDevDetected = IMG_FALSE; } /*start j00140427 add clock and regulator*/ if (NULL != gvdec_clk) { clk_put( gvdec_clk); gvdec_clk = NULL; } regulator_put(gvdec_regulator.consumer); memset(&gvdec_regulator,0,sizeof(gvdec_regulator)); /*end j00140427 add clock and regulator*/ if(psSysDev != psInfo) { printk(KERN_ERR "VxD: Failed to free the Device\n"); return; } //Free device name if (gpszDevName != IMG_NULL) { IMG_FREE(gpszDevName); gpszDevName = IMG_NULL; } if(IMG_NULL != psSysDev) { free_irq(module_irq, psSysDev); } psSysDev = IMG_NULL; return; }
/*! ****************************************************************************** @Function wrapu_fnCompDisconnect ******************************************************************************/ static IMG_RESULT wrapu_fnCompDisconnect ( IMG_HANDLE hAttachHandle, IMG_VOID * pvCompAttachmentData ) { WRAPU_sAttachContext * psAttachContext = pvCompAttachmentData; /* Destroy the bucket and it's resources...*/ RMAN_DestroyBucket(psAttachContext->hResBHandle); /* If we opened a device...*/ if (psAttachContext->hSysDevHandle != IMG_NULL) { SYSDEVKM_CloseDevice(psAttachContext->hSysDevHandle); } /* Free attachment context...*/ IMG_FREE(psAttachContext); /* Return success...*/ return IMG_SUCCESS; }
static IMG_RESULT perflog_CreateBuffer(perflog_Buffer **ppsBuffer, IMG_SIZE stBuffSize) { perflog_Buffer *psBuffer = NULL; if(ppsBuffer == NULL || *ppsBuffer != NULL) { REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot create buffer: invalid parameters"); return IMG_ERROR_INVALID_PARAMETERS; } //alloc buffer struct *ppsBuffer = (perflog_Buffer*) IMG_MALLOC(sizeof(perflog_Buffer)); IMG_ASSERT(*ppsBuffer != IMG_NULL); if(*ppsBuffer == IMG_NULL) { REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot allocate memory for buffer struct"); return IMG_ERROR_MALLOC_FAILED; } psBuffer = *ppsBuffer; //alloc buffer itself psBuffer->pui64Buffer = (IMG_UINT64*) IMG_MALLOC(sizeof(IMG_UINT64) * stBuffSize); IMG_ASSERT(psBuffer->pui64Buffer != IMG_NULL); if(psBuffer->pui64Buffer == IMG_NULL) { IMG_FREE(psBuffer); REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot allocate buffers"); return IMG_ERROR_MALLOC_FAILED; } IMG_MEMSET(psBuffer->pui64Buffer, 0,sizeof(IMG_UINT64) * stBuffSize); psBuffer->stIter = 0; psBuffer->stBufferSize = stBuffSize; return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RMAN_DestroyBucket ******************************************************************************/ IMG_VOID RMAN_DestroyBucket( IMG_HANDLE hResBHandle ) { RMAN_sBucket * psBucket = (RMAN_sBucket *)hResBHandle; IMG_ASSERT(gInitialised); IMG_ASSERT(psBucket != IMG_NULL); if (psBucket== IMG_NULL) { return; } IMG_ASSERT(psBucket->ui32BucketIndex < RMAN_CRESID_MAX_BUCKET_INDEX); IMG_ASSERT(gapsBucket[psBucket->ui32BucketIndex] != IMG_NULL); /* Free all resources from the bucket...*/ RMAN_FreeResources(hResBHandle, RMAN_TYPE_P1); RMAN_FreeResources(hResBHandle, RMAN_TYPE_P2); RMAN_FreeResources(hResBHandle, RMAN_TYPE_P3); RMAN_FreeResources(hResBHandle, RMAN_ALL_TYPES); /* free sticky resources last: other resources are dependent on them */ RMAN_FreeResources(hResBHandle, RMAN_STICKY); /* Use proper locking around global buckets. */ SYSOSKM_DisableInt(); /* Free from array of bucket pointers...*/ gapsBucket[psBucket->ui32BucketIndex] = IMG_NULL; SYSOSKM_EnableInt(); /* Free the bucket itself...*/ IDGEN_DestroyContext(psBucket->hIdGenerator); IMG_FREE(psBucket); }
/*! ****************************************************************************** @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 DMANKM_DevDisconnectComplete ******************************************************************************/ IMG_RESULT DMANKM_DevDisconnectComplete(IMG_HANDLE hConnHandle) { IMG_UINT32 ui32Result; DMANKM_sConnContext * psConnContext = hConnHandle; DMANKM_sConnContext * psInitConnContext; DMANKM_sDevContext * psDevContext = psConnContext->psDevContext; IMG_HANDLE hProcessId; /* Disconnect components attached to this connection...*/ ui32Result = dmankm_DisconnectComps(psConnContext); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Save the process id...*/ hProcessId = psConnContext->hProcessId; /* Remove and free this connection...*/ LST_remove(&psDevContext->sConnList, psConnContext); RMAN_FreeResource(psConnContext->hResHandle); IMG_FREE(psConnContext); /* Update the connection count...*/ psDevContext->ui32ConnCnt--; /* If connection count 0...*/ if (psDevContext->ui32ConnCnt == 0) { /* Deinitailise the device....*/ psInitConnContext = (DMANKM_sConnContext *) LST_first( &psDevContext->sConnList); if(psInitConnContext == NULL) { IMG_ASSERT(psInitConnContext != IMG_NULL); return IMG_ERROR_GENERIC_FAILURE; } else { IMG_ASSERT(psInitConnContext->bInitConn); } /* Deregister the LISR...*/ if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) { SYSDEVU_RemoveDevKmLisr(psDevContext->hSysDevHandle); } /* Deregister the HISR...*/ if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) { if (psDevContext->hHISRHandle) { IMG_HANDLE HISRHandle = psDevContext->hHISRHandle; psDevContext->hHISRHandle = IMG_NULL; SYSOSKM_DestroyKmHisr(HISRHandle); } } /* If we have a deinitialise function...*/ if (psDevContext->sDevRegister.pfnDevDeinit != IMG_NULL ) { psDevContext->sDevRegister.pfnDevDeinit(psDevContext, psInitConnContext, psDevContext->pvDevInstanceData); } if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE) == 0) { /* Power the device off. */ SYSDEVU_SetPowerState(psDevContext->hSysDevHandle, SYSOSKM_POWERSTATE_S5, IMG_FALSE); } /* Disconnect components attached to the implicit connection...*/ ui32Result = dmankm_DisconnectComps(psInitConnContext); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Remove and free the implicit connection...*/ LST_remove(&psDevContext->sConnList, psInitConnContext); RMAN_FreeResource(psInitConnContext->hResHandle); IMG_FREE(psInitConnContext); /* Destroy the resource bucket used for connections and attachments...*/ RMAN_DestroyBucket(psDevContext->hResBHandle); psDevContext->hResBHandle = IMG_NULL; /* If we opened the device with SYSDEVKM...*/ if (psDevContext->hSysDevHandle != IMG_NULL ) { /* Close it...*/ SYSDEVU_CloseDevice(psDevContext->hSysDevHandle); psDevContext->hSysDevHandle = IMG_NULL; } } /* Let the Process Manager know the connection has been broken...*/ PMAN_DevDisconnectComplete(hProcessId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(psDevContext); /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @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 POOL_ResDestroy ******************************************************************************/ IMG_RESULT POOL_ResDestroy( IMG_HANDLE hPoolResHandle, IMG_BOOL bForce ) { POOL_sResource * psResource = hPoolResHandle; POOL_sResPool * psResPool; POOL_sResource * psOrigResource; 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; } psResPool = psResource->psResPool; /* Lock the pool...*/ SYSOSKM_LockMutex(psResPool->hMutexHandle); /* If this is a clone...*/ if (psResource->bIsClone) { IMG_ASSERT(0); // We need to check this works. /* Get access to the original...*/ psOrigResource = psResource->psOrigResource; IMG_ASSERT(psOrigResource != IMG_NULL); if (psOrigResource == IMG_NULL) { ui32Result = IMG_ERROR_UNEXPECTED_STATE; goto error; } IMG_ASSERT(!psOrigResource->bIsClone); if (psOrigResource->bIsClone) { ui32Result = IMG_ERROR_UNEXPECTED_STATE; goto error; } /* 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; } /* If there are still outstanding references...*/ if ( (!bForce) && (psResource->ui32RefCnt != 0) ) { IMG_ASSERT(0); // We may need to mark the resource and destroy it when // there are no outstanding references /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); /* Return IMG_SUCCESS...*/ return IMG_SUCCESS; } /* Check clone list is empty...*/ psCloneResource = LST_first(&psResource->sCloneResList); IMG_ASSERT(psCloneResource == IMG_NULL); /* Has the resource outstanding references...*/ if (psResource->ui32RefCnt != 0) { /* Remove the resource from the active list...*/ LST_remove(&psResPool->sActResList, psResource); } else { /* Remove the resource from the free list...*/ LST_remove(&psResPool->sFreeResList, 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; } /* Call the resource destructor...*/ psResource->pfnDestructor(psResource->pvParam); IMG_FREE(psResource); /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); /* Return IMG_SUCCESS...*/ return IMG_SUCCESS; error: SYSOSKM_UnlockMutex(psResPool->hMutexHandle); error_nolock: return ui32Result; }
/*! ****************************************************************************** @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; }