/*! ****************************************************************************** @Function POOL_Deinitialise ******************************************************************************/ IMG_VOID POOL_Deinitialise(IMG_VOID) { POOL_sResPool * psResPool; IMG_ASSERT(0); /* Disable interrupts. */ SYSOSKM_DisableInt(); /* If not initialised...*/ if (!gInitialised) { /* Destroy any active pools...*/ psResPool = (POOL_sResPool *)LST_first(&gsPoolList); while (psResPool != IMG_NULL) { POOL_PoolDestroy(psResPool); psResPool = (POOL_sResPool *)LST_first(&gsPoolList); } /* Set initialised flag...*/ gInitialised = IMG_FALSE; } /* Enable interrupts. */ SYSOSKM_EnableInt(); }
/*! ****************************************************************************** @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; }
BOOL Del_Cur_Item ( LNK_LST *lst ) { LST_ITM *p, *last; LST_ITM *next_item = LST_nxt(lst); if ( LST_Empty(lst) ) return FALSE; /* not in the list => nothing to delete */ last = NULL; for ( p=LST_first(lst); p!=NULL; p=LST_next(p) ) { if ( LST_next(p) == next_item ) { if ( last == NULL ) /* it was the first item in the list */ LST_first(lst) = LST_next(p); else /* it was not the first item in the list */ LST_next(last) = LST_next(p); item_free ( p ); /* put deleted item into the free list */ decr_LST_len(lst); return TRUE; /* it was deleted from the list => return TRUE */ } last = p; } /* If we get to here, we went through the list, but we did not find * an item with an LST_next field matching the next item of the list. */ return FALSE; }
/*! ****************************************************************************** @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; }
void Add_First_Item ( LNK_LST *lst, tlst_val val ) { register LST_ITM *p; p = item_alloc(); LST_val(p) = val; LST_next(p) = LST_first(lst); LST_first(lst) = p; incr_LST_len(lst); }
/*! ****************************************************************************** @Function RESOURCE_GetNumPict ******************************************************************************/ IMG_UINT32 RESOURCE_GetNumPict( LST_T * psList ) { RESOURCE_sListElem * psListElem = NULL; IMG_UINT32 ui32NumPict = 0; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); if (psList == IMG_NULL) { goto error; } /* Find the next unused buffer in the list. */ psListElem = LST_first(psList); while (psListElem) { if (((VDECDD_sStrUnit*)psListElem->pvItem)->eStrUnitType == VDECDD_STRUNIT_PICTURE_START) { ui32NumPict++; } psListElem = LST_next(psListElem); } error: return ui32NumPict; }
/*! ****************************************************************************** @Function RESOURCE_ListGetNum ******************************************************************************/ IMG_UINT32 RESOURCE_ListGetNum( LST_T * psList ) { RESOURCE_sListElem * psListElem = IMG_NULL; IMG_UINT32 ui32NumItems = 0; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); if (psList == IMG_NULL) { goto error; } /* Find the next unused buffer in the list. */ psListElem = LST_first(psList); while (psListElem) { ui32NumItems++; psListElem = LST_next(psListElem); } error: return ui32NumItems; }
/*! ****************************************************************************** @Function RESOURCE_ListGetById ******************************************************************************/ IMG_VOID * RESOURCE_ListGetById( LST_T * psList, IMG_UINT32 ui32Id ) { RESOURCE_sListElem * psListElem = IMG_NULL; IMG_VOID * pvItem = IMG_NULL; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); if (psList == IMG_NULL) { goto error; } /* Find the next unused buffer in the list. */ psListElem = LST_first(psList); while (psListElem) { if (psListElem->ui32Id == ui32Id) { /* Take a copy of the item. */ RESOURCE_ItemUse(psListElem->pui32RefCount); pvItem = psListElem->pvItem; break; } psListElem = LST_next(psListElem); } error: return pvItem; }
/*! ****************************************************************************** @Function RESOURCE_ListGetAvail ******************************************************************************/ IMG_VOID * RESOURCE_ListGetAvail( 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; } /* Find the next unused item in the list. */ psListElem = LST_first(psList); while (psListElem) { if (RESOURCE_ItemIsAvailable(psListElem->pui32RefCount)) { /* Take a copy to the item. */ RESOURCE_ItemUse(psListElem->pui32RefCount); pvItem = psListElem->pvItem; break; } psListElem = LST_next(psListElem); } error: return pvItem; }
/*! ****************************************************************************** @Function RESOURCE_ListPeekHead ******************************************************************************/ IMG_VOID * RESOURCE_ListPeekHead( 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_first(psList); if (psListElem) { pvItem = psListElem->pvItem; } error: return pvItem; }
/*! ****************************************************************************** @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; }
__inline static SYSDEVU_sInfo *findDeviceById(IMG_UINT32 devId) { SYSDEVU_sInfo *dev = (SYSDEVU_sInfo *)LST_first(&gsDevList); while(dev != IMG_NULL) { if(devId == dev->ui32DeviceId) return dev; dev = LST_next(dev); } return IMG_NULL; }
__inline static SYSDEVU_sInfo *findDeviceByName(IMG_CHAR *devName) { SYSDEVU_sInfo *dev = (SYSDEVU_sInfo *)LST_first(&gsDevList); while(dev != IMG_NULL) { if(!IMG_STRCMP(devName, dev->sDevInfo.pszDeviceName)) return dev; dev = LST_next(dev); } return IMG_NULL; }
void Add_Item_Dup ( LNK_LST *lst, tlst_val val ) { LST_ITM *p; LST_ITM *last; if (LST_Empty(lst)) { LST_first(lst) = p = item_alloc(); LST_val(p) = val; incr_LST_len(lst); return; } /* * Find the end of the list. */ last = NULL; /* unnecessary except to eliminate warning msg */ for (p=LST_first(lst); p!=NULL; p=LST_next(p)) last = p; /* * Append a new item to the end of the list. */ LST_next(last) = p = item_alloc(); LST_val(p) = val; incr_LST_len(lst); /* * If the pointer to the next item in the list is NULL, i.e. when * stepping through the list the end was reached, then make the next * item be this new item. */ if (LST_nxt(lst) == NULL) LST_nxt(lst) = p; #ifdef BB_VALIDATE_LIST Validate_List ( lst ); #endif return; }
INT32 LST_Len ( LNK_LST *lst ) { register INT32 count = 0; register LST_ITM *p; for (p=LST_first(lst); p!=NULL; p=LST_next(p)) ++count; return count; }
void Free_List ( LNK_LST *lst ) { register LST_ITM *p1, *p2; for (p1=LST_first(lst); p1!=NULL; p1=p2) { p2 = LST_next(p1); item_free(p1); } Init_List(lst); }
/*! ****************************************************************************** @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; }
BOOL Add_Item ( LNK_LST *lst, tlst_val val) { register LST_ITM *p, *last; if (LST_Empty(lst)) { LST_first(lst) = p = item_alloc(); LST_val(p) = val; incr_LST_len(lst); return TRUE; } last = NULL; /* unnecessary except to eliminate warning msg */ for (p=LST_first(lst); p!=NULL; p=LST_next(p)) { if (LST_val(p) == val) return FALSE; /* already in the list => return FALSE */ last = p; } /* * If we get to here, we went through the list without finding a * matching item. Append a new item to the end of the list. */ LST_next(last) = p = item_alloc(); LST_val(p) = val; incr_LST_len(lst); /* * If the pointer to the next item in the list is NULL, i.e. when * stepping through the list the end was reached, then make the next * item be this new item. */ if (LST_nxt(lst) == NULL) LST_nxt(lst) = p; return TRUE; }
/*! ****************************************************************************** @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; }
BOOL Del_Item ( LNK_LST *lst, tlst_val val ) { register LST_ITM *p, *last; if (LST_Empty(lst)) return FALSE; /* not in the list => nothing to delete */ last = NULL; for (p=LST_first(lst); p!=NULL; p=LST_next(p)) { if (LST_val(p) == val) { if (LST_nxt(lst) == p) /* item being deleted is 'next' item */ LST_nxt(lst) = LST_next(p); if (last == NULL) /* it was the first item in the list */ LST_first(lst) = LST_next(p); else /* it was not the first item in the list */ LST_next(last) = LST_next(p); item_free(p); /* put deleted item into the free list */ decr_LST_len(lst); return TRUE; /* it was deleted from the list => return TRUE */ } last = p; } /* * If we get to here, we went through the list searching for the item * but could not find it. Just return FALSE. */ return FALSE; }
BOOL Validate_List ( LNK_LST *lst ) { INT32 count = LST_Len(lst); LST_ITM *p; for ( p=LST_first(lst); p!=NULL; p=LST_next(p) ) { if ( --count < 0 ) break; } if ( count != 0 ) { if ( Get_Trace ( TKIND_INFO, TINFO_HARD, 0 ) ) { fprintf ( TFile, "##### Validate_List: Invalid count #####\n" ); count = 10*LST_Len(lst); for ( p=LST_first(lst); p!=NULL; p=LST_next(p) ) { if ( --count < 0 ) break; fprintf ( TFile, " 0x%08x: %d\n", p, LST_val(p) ); } } FmtAssert ( FALSE, ( "Validate_List: invalid count %d", LST_Len(lst) ) ); return FALSE; } return TRUE; }
BOOL Item_In_List ( LNK_LST *lst, tlst_val val ) { register LST_ITM *p; if (LST_Empty(lst)) return FALSE; /* empty list => not in the list */ for (p=LST_first(lst); p!=NULL; p=LST_next(p)) if (LST_val(p) == val) return TRUE; /* found it */ /* * If we get to here, we went through the list searching for the item * but could not find it. Just return FALSE. */ return FALSE; }
static void *perflog_start(struct seq_file *s, loff_t *pos) { perflog_Buffer *psBuffer; loff_t tmpPos = *pos; //prevent from writing while one reads file SYSOSKM_LockMutex(gsPerfFile.hMutexHandle); //jump to appropriate buffer psBuffer = LST_first(&gsPerfFile.sBufferList); while(psBuffer && tmpPos > 0) { tmpPos--; psBuffer = LST_next(psBuffer); } return psBuffer; }
/*! ****************************************************************************** @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 DMANKM_LocateDevice ******************************************************************************/ IMG_RESULT DMANKM_LocateDevice(IMG_CHAR * pszDeviceName, IMG_HANDLE * phDevHandle) { DMANKM_sDevContext * psDevContext; /* Search list of registered devices for this device...*/ IMG_ASSERT(gbDevListInitialised); psDevContext = (DMANKM_sDevContext *) LST_first(&gsDevList); while ((psDevContext != IMG_NULL )&& IMG_STRCMP(psDevContext->pszDeviceName, pszDeviceName) ) { psDevContext = (DMANKM_sDevContext *) LST_next(psDevContext); } *phDevHandle = psDevContext; /* If not found...*/ if (psDevContext == IMG_NULL ) { return IMG_ERROR_DEVICE_NOT_FOUND; } return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RESOURCE_ListReuseItem ******************************************************************************/ IMG_VOID * RESOURCE_ListReuseItem( LST_T * psList, IMG_VOID * pvItem ) { RESOURCE_sListElem * psListElem = IMG_NULL; IMG_VOID * pvRetItem = IMG_NULL; /* Check input params. */ IMG_ASSERT(IMG_NULL != psList); IMG_ASSERT(IMG_NULL != pvItem); if (psList == IMG_NULL || pvItem == IMG_NULL) { goto error; } /* Find the specified item in the list. */ psListElem = LST_first(psList); while (psListElem) { if (psListElem->pvItem == pvItem) { /* Take a copy to the item. */ RESOURCE_ItemUse(psListElem->pui32RefCount); pvRetItem = pvItem; break; } psListElem = LST_next(psListElem); } error: return pvRetItem; }
/*! ****************************************************************************** @Function dman_LocateComponentKM ******************************************************************************/ static IMG_BOOL dman_LocateComponentKM(IMG_CHAR * pszCompName, DMANKM_sConnContext * psConnContext, DMANKM_sAttachContext ** ppsAttachContext) { DMANKM_sAttachContext * psAttachContext; /* Search list of attached resource allocator for this connection...*/ psAttachContext = (DMANKM_sAttachContext *) LST_first( &psConnContext->sAttachList); while ((psAttachContext != IMG_NULL )&& (IMG_STRCMP(psAttachContext->pszCompName, pszCompName) != 0) ){ psAttachContext = (DMANKM_sAttachContext *)LST_next(psAttachContext); } /* If resource allocator found...*/ if (psAttachContext != IMG_NULL ) { *ppsAttachContext = psAttachContext; return IMG_TRUE; } /* Device not found....*/ return IMG_FALSE; }
/*! ****************************************************************************** @Function DMANKM_KmPowerEvent ******************************************************************************/ IMG_VOID DMANKM_KmPowerEvent( SYSOSKM_ePowerTrans ePowerTrans, SYSOSKM_ePowerState ePowerState, IMG_VOID * pvParam) { DMANKM_sDevContext * psDevContext; /* Search list of registered devices for this device...*/ IMG_ASSERT(gbDevListInitialised); psDevContext = (DMANKM_sDevContext *) LST_first(&gsDevList); while (psDevContext != IMG_NULL ) { if (((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE) == 0) && (psDevContext->ui32ConnCnt != 0)) { switch (ePowerTrans) { case SYSOSKM_POWERTRANS_PRE: switch (ePowerState) { case SYSOSKM_POWERSTATE_S0: if (psDevContext->sDevRegister.pfnDevPowerPostS0) SYSDEVU_SetPowerState(psDevContext->hSysDevHandle, ePowerState, IMG_FALSE); break; case SYSOSKM_POWERSTATE_S5: if (psDevContext->sDevRegister.pfnDevPowerPreS5) { if (!((psDevContext->ui8ApmPpmFlags & DMAN_DPPM) || (psDevContext->ui8ApmPpmFlags & DMAN_DAPM))) { psDevContext->sDevRegister.pfnDevPowerPreS5( psDevContext, psDevContext->pvDevInstanceData); psDevContext->ui8ApmPpmFlags |= DMAN_DPPM; } else if ((psDevContext->ui8ApmPpmFlags & DMAN_DAPM) && !(psDevContext->ui8ApmPpmFlags & DMAN_DPPM)) { psDevContext->ui8ApmPpmFlags |= DMAN_DPPM; } else { IMG_ASSERT( !"PPM Off Called while core is off by PPM"); } } break; default: /* Unrecognised power state. */ IMG_ASSERT(IMG_FALSE); break; } ; break; case SYSOSKM_POWERTRANS_POST: switch (ePowerState) { case SYSOSKM_POWERSTATE_S0: if (psDevContext->sDevRegister.pfnDevPowerPostS0) { if ((psDevContext->ui8ApmPpmFlags & DMAN_DPPM) && !(psDevContext->ui8ApmPpmFlags & DMAN_DAPM)) { psDevContext->sDevRegister.pfnDevPowerPostS0( psDevContext, psDevContext->pvDevInstanceData); psDevContext->ui8ApmPpmFlags &= ~DMAN_DPPM; psDevContext->ui8ApmPpmFlags |= DMAN_DPPM_TURNED_ON; } else if ((psDevContext->ui8ApmPpmFlags & DMAN_DPPM) && (psDevContext->ui8ApmPpmFlags & DMAN_DAPM)) { psDevContext->ui8ApmPpmFlags &= ~DMAN_DPPM; } else { IMG_ASSERT( !"PPM On Called while core is either On or off by APM"); } } break; case SYSOSKM_POWERSTATE_S5: if (psDevContext->sDevRegister.pfnDevPowerPreS5) SYSDEVU_SetPowerState(psDevContext->hSysDevHandle, ePowerState, IMG_FALSE); break; default: /* Unrecognised power state. */ IMG_ASSERT(IMG_FALSE); break; } ; break; default: /* Unrecognised power transition. */ IMG_ASSERT(IMG_FALSE); break; }; } psDevContext = (DMANKM_sDevContext *) LST_next(psDevContext); } }
/*! ****************************************************************************** @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_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; }