/* * ========= MGR_Destroy ========= * This function is invoked during bridge driver unloading.Frees MGR object. */ DSP_STATUS MGR_Destroy(struct MGR_OBJECT *hMgrObject) { DSP_STATUS status = DSP_SOK; struct MGR_OBJECT *pMgrObject = (struct MGR_OBJECT *)hMgrObject; DBC_Require(cRefs > 0); DBC_Require(MEM_IsValidHandle(hMgrObject, SIGNATURE)); GT_1trace(MGR_DebugMask, GT_ENTER, "Entering MGR_Destroy hMgrObject 0x%x\n", hMgrObject); /* Free resources */ if (hMgrObject->hDcdMgr) DCD_DestroyManager(hMgrObject->hDcdMgr); MEM_FreeObject(pMgrObject); /* Update the Registry with NULL for MGR Object */ (void)CFG_SetObject(0, REG_MGR_OBJECT); GT_2trace(MGR_DebugMask, GT_ENTER, "Exiting MGR_Destroy: hMgrObject: 0x%x\t" "status: 0x%x\n", hMgrObject, status); DBC_Ensure(DSP_FAILED(status) || !MEM_IsValidHandle(hMgrObject, SIGNATURE)); return status; }
/* * ======== STRM_Issue ======== * Purpose: * Issues a buffer on a stream */ DSP_STATUS STRM_Issue(struct STRM_OBJECT *hStrm, IN u8 *pBuf, u32 ulBytes, u32 ulBufSize, u32 dwArg) { struct WMD_DRV_INTERFACE *pIntfFxns; DSP_STATUS status = DSP_SOK; void *pTmpBuf = NULL; DBC_Require(cRefs > 0); DBC_Require(pBuf != NULL); GT_4trace(STRM_debugMask, GT_ENTER, "STRM_Issue: hStrm: 0x%x\tpBuf: " "0x%x\tulBytes: 0x%x\tdwArg: 0x%x\n", hStrm, pBuf, ulBytes, dwArg); pIntfFxns = hStrm->hStrmMgr->pIntfFxns; if (hStrm->uSegment != 0) { pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, (void *)pBuf, CMM_VA2DSPPA); if (pTmpBuf == NULL) status = DSP_ETRANSLATE; } if (DSP_SUCCEEDED(status)) { status = (*pIntfFxns->pfnChnlAddIOReq) (hStrm->hChnl, pBuf, ulBytes, ulBufSize, (u32) pTmpBuf, dwArg); } if (status == CHNL_E_NOIORPS) status = DSP_ESTREAMFULL; return status; }
/** ============================================================================ * @func LDRV_MPLIST_isEmpty * * @desc check for an empty list. * * @modif None. * ============================================================================ */ EXPORT_API Bool LDRV_MPLIST_isEmpty (IN ProcessorId dspId, IN List * list ) { Bool retVal = FALSE ; LDRV_MPLIST_Object * mplistState ; Uint32 temp ; TRC_2ENTER ("LDRV_MPLIST_isEmpty", dspId, list) ; DBC_Require (IS_VALID_PROCID(dspId)) ; DBC_Require (list != NULL) ; DBC_Assert (LDRV_MPLIST_IsInitialized [dspId] == TRUE) ; mplistState = &(LDRV_MPLIST_State [dspId]) ; temp = SWAP_LONG (DSP_addrConvert (dspId, (Uint32) &((list)->head), GppToDsp), mplistState->wordSwap) ; if ( ((Uint32) (list)->head.next) == temp) { retVal = TRUE ; } TRC_1LEAVE ("LDRV_MPLIST_isEmpty", retVal) ; return retVal ; }
/* * ======== STRM_FreeBuffer ======== * Purpose: * Frees the buffers allocated for a stream. */ DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, u8 **apBuffer, u32 uNumBufs, struct PROCESS_CONTEXT *pr_ctxt) { DSP_STATUS status = DSP_SOK; u32 i = 0; HANDLE hSTRMRes = NULL; DBC_Require(cRefs > 0); DBC_Require(apBuffer != NULL); for (i = 0; i < uNumBufs; i++) { DBC_Assert(hStrm->hXlator != NULL); status = CMM_XlatorFreeBuf(hStrm->hXlator, apBuffer[i]); if (DSP_FAILED(status)) break; apBuffer[i] = NULL; } if (DSP_SUCCEEDED(status)) { if (DRV_GetSTRMResElement(hStrm, hSTRMRes, pr_ctxt) != DSP_ENOTFOUND) DRV_ProcUpdateSTRMRes(uNumBufs-i, hSTRMRes); } return status; }
/** ============================================================================ * @func LIST_GetHead * * @desc Pops the head off the list and returns a pointer to it. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_GetHead (IN List * list, OUT ListElement ** headElement) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_GetHead", list, headElement) ; DBC_Require (list != NULL) ; DBC_Require (headElement != NULL) ; if ((list == NULL) || (headElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (LIST_IsEmpty (list)) { *headElement = NULL ; } else { *headElement = list->head.next ; list->head.next = (*headElement)->next ; (*headElement)->next->prev = &list->head ; } } TRC_1LEAVE ("LIST_GetHead", status) ; return status ; }
/** ============================================================================ * @func LDRV_MPCS_create * * @desc This function creates and initializes an instance of the MPCS * object. * The memory for the object may or may not be provided by the user. * If provided by the user, the memory for the object must be shared * across the processors using the MPCS. It must also already be mapped * into user space for OSes supporting user/kernel separation. * * @modif None. * ============================================================================ */ EXPORT_API DSP_STATUS LDRV_MPCS_create (IN ProcessorId dspId, IN MPCS_ShObj * mpcsObj) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LDRV_MPCS_create", dspId, mpcsObj) ; DBC_Require (IS_VALID_PROCID (dspId)) ; DBC_Require (mpcsObj != NULL) ; mpcsObj->turn = SELF ; #if defined (DDSP_PROFILE) mpcsObj->gppMpcsObj.conflicts = 0 ; mpcsObj->gppMpcsObj.numCalls = 0 ; mpcsObj->dspMpcsObj.conflicts = 0 ; mpcsObj->dspMpcsObj.numCalls = 0 ; #endif status = LDRV_MPCS_OS_create (dspId, mpcsObj) ; mpcsObj->dspMpcsObj.localLock = 0 ; mpcsObj->gppMpcsObj.flag = (Uint16) MPCS_FREE ; mpcsObj->dspMpcsObj.flag = (Uint16) MPCS_FREE ; mpcsObj->gppMpcsObj.freeObject = (Uint16) FALSE ; mpcsObj->dspMpcsObj.freeObject = (Uint16) FALSE ; mpcsObj->dspMpcsObj.mpcsEntryAddr = 0 ; mpcsObj->gppMpcsObj.mpcsEntryAddr = 0 ; TRC_1LEAVE ("LDRV_MPCS_create", status) ; return status ; }
/* * ======== DBLL_unload ======== */ void DBLL_unload(struct DBLL_LibraryObj *lib, struct DBLL_Attrs *attrs) { struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib; s32 err = 0; DBC_Require(cRefs > 0); DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); DBC_Require(zlLib->loadRef > 0); GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_unload: lib: 0x%x\n", lib); zlLib->loadRef--; /* Unload only if reference count is 0 */ if (zlLib->loadRef != 0) goto func_end; zlLib->pTarget->attrs = *attrs; if (zlLib->mHandle) { err = Dynamic_Unload_Module(zlLib->mHandle, &zlLib->symbol.dlSymbol, &zlLib->allocate.dlAlloc, &zlLib->init.dlInit); if (err != 0) { GT_1trace(DBLL_debugMask, GT_5CLASS, "Dynamic_Unload_Module failed: 0x%x\n", err); } } /* remove symbols from symbol table */ if (zlLib->symTab != NULL) { GH_delete(zlLib->symTab); zlLib->symTab = NULL; } /* delete DOFF desc since it holds *lots* of host OS * resources */ dofClose(zlLib); func_end: DBC_Ensure(zlLib->loadRef >= 0); }
/** ============================================================================ * @func LIST_PutTail * * @desc Adds the specified element to the tail of the list. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_PutTail (IN List * list, IN ListElement * element) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_PutTail", list, element) ; DBC_Require (list != NULL) ; DBC_Require (element != NULL) ; if ((list == NULL) || (element == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { element->prev = list->head.prev ; element->next = &list->head ; list->head.prev = element ; element->prev->next = element ; } DBC_Assert ( (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list))) || (DSP_FAILED (status))); TRC_1LEAVE ("LIST_PutTail", status) ; return status ; }
/* * ======== DBLL_create ======== */ DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, struct DBLL_Attrs *pAttrs) { struct DBLL_TarObj *pzlTarget; DSP_STATUS status = DSP_SOK; DBC_Require(cRefs > 0); DBC_Require(pAttrs != NULL); DBC_Require(pTarget != NULL); GT_2trace(DBLL_debugMask, GT_ENTER, "DBLL_create: pTarget: 0x%x pAttrs: " "0x%x\n", pTarget, pAttrs); /* Allocate DBL target object */ MEM_AllocObject(pzlTarget, struct DBLL_TarObj, DBLL_TARGSIGNATURE); if (pTarget != NULL) { if (pzlTarget == NULL) { GT_0trace(DBLL_debugMask, GT_6CLASS, "DBLL_create: Memory allocation" " failed\n"); *pTarget = NULL; status = DSP_EMEMORY; } else { pzlTarget->attrs = *pAttrs; *pTarget = (struct DBLL_TarObj *)pzlTarget; } DBC_Ensure((DSP_SUCCEEDED(status) && MEM_IsValidHandle(((struct DBLL_TarObj *)(*pTarget)), DBLL_TARGSIGNATURE)) || (DSP_FAILED(status) && *pTarget == NULL)); } return status; }
/* * ======== DBLL_getCAddr ======== * Get address of a "C" name in the specified library. */ bool DBLL_getCAddr(struct DBLL_LibraryObj *zlLib, char *name, struct DBLL_Symbol **ppSym) { struct Symbol *sym; char cname[MAXEXPR + 1]; bool status = false; DBC_Require(cRefs > 0); DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); DBC_Require(ppSym != NULL); DBC_Require(zlLib->symTab != NULL); DBC_Require(name != NULL); cname[0] = '_'; strncpy(cname + 1, name, sizeof(cname) - 2); cname[MAXEXPR] = '\0'; /* insure '\0' string termination */ /* Check for C name, if not found */ sym = (struct Symbol *)GH_find(zlLib->symTab, cname); if (sym != NULL) { *ppSym = &sym->value; status = true; } return status; }
/* * ======== DBLL_close ======== */ void DBLL_close(struct DBLL_LibraryObj *zlLib) { struct DBLL_TarObj *zlTarget; DBC_Require(cRefs > 0); DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); DBC_Require(zlLib->openRef > 0); zlTarget = zlLib->pTarget; GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_close: lib: 0x%x\n", zlLib); zlLib->openRef--; if (zlLib->openRef == 0) { /* Remove library from list */ if (zlTarget->head == zlLib) zlTarget->head = zlLib->next; if (zlLib->prev) (zlLib->prev)->next = zlLib->next; if (zlLib->next) (zlLib->next)->prev = zlLib->prev; /* Free DOF resources */ dofClose(zlLib); if (zlLib->fileName) MEM_Free(zlLib->fileName); /* remove symbols from symbol table */ if (zlLib->symTab) GH_delete(zlLib->symTab); /* remove the library object itself */ MEM_FreeObject(zlLib); zlLib = NULL; } }
/* * ======== COD_ReadSection ======== * Purpose: * Retrieve the content of a code section given the section name. */ DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect, OUT char *pstrContent, IN u32 cContentSize) { DSP_STATUS status = DSP_SOK; DBC_Require(cRefs > 0); DBC_Require(lib != NULL); DBC_Require(IsValid(lib->hCodMgr)); DBC_Require(pstrSect != NULL); DBC_Require(pstrContent != NULL); GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_ReadSection Args: 0x%x," " 0x%x, 0x%x, 0x%x\n", lib, pstrSect, pstrContent, cContentSize); if (lib != NULL) { status = lib->hCodMgr->fxns.readSectFxn(lib->dbllLib, pstrSect, pstrContent, cContentSize); if (DSP_FAILED(status)) { GT_1trace(COD_debugMask, GT_7CLASS, "COD_ReadSection failed: 0x%lx\n", status); } } else { status = COD_E_NOSYMBOLSLOADED; GT_0trace(COD_debugMask, GT_7CLASS, "COD_ReadSection: No Symbols loaded\n"); } return status; }
/* * ======== COD_GetSymValue ======== * Purpose: * Retrieve the value for the specified symbol. The symbol is first * searched for literally and then, if not found, searched for as a * C symbol. * */ DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hMgr, char *pstrSym, u32 *pulValue) { struct DBLL_Symbol *pSym; DBC_Require(cRefs > 0); DBC_Require(IsValid(hMgr)); DBC_Require(pstrSym != NULL); DBC_Require(pulValue != NULL); GT_3trace(COD_debugMask, GT_ENTER, "Entered COD_GetSymValue Args \t\n" "hMgr: 0x%x\t\npstrSym: 0x%x\t\npulValue: 0x%x\n", hMgr, pstrSym, pulValue); if (hMgr->baseLib) { if (!hMgr->fxns.getAddrFxn(hMgr->baseLib, pstrSym, &pSym)) { if (!hMgr->fxns.getCAddrFxn(hMgr->baseLib, pstrSym, &pSym)) { GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: " "Symbols not found\n"); return COD_E_SYMBOLNOTFOUND; } } } else { GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: " "No Symbols loaded\n"); return COD_E_NOSYMBOLSLOADED; } *pulValue = pSym->value; return DSP_SOK; }
/** ============================================================================ * @func KFILEDEF_Tell * * @desc Returns the current file pointer position for the specified * file handle. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS KFILEDEF_Tell (IN Void * fileHandle, OUT Int32 * pos) { DSP_STATUS status = DSP_SOK ; KFILEDEF_Object * fileObj = NULL ; TRC_2ENTER ("KFILEDEF_Tell", fileObj, pos) ; DBC_Require (fileHandle != NULL) ; DBC_Require (pos != NULL) ; if (pos == NULL) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { fileObj = (KFILEDEF_Object *) fileHandle ; *pos = fileObj->curPos ; DBC_Assert (*pos == fileObj->fileDesc->f_pos) ; } DBC_Ensure ( (DSP_SUCCEEDED (status) && (pos != NULL) && (*pos >= 0)) || (DSP_FAILED (status))) ; TRC_1LEAVE ("KFILEDEF_Tell", status) ; return status ; }
/** ============================================================================ * @func PRCS_Delete * * @desc Frees up resources used by the specified object. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS PRCS_Delete (IN PrcsObject * prcsObj) { DSP_STATUS status = DSP_SOK ; TRC_1ENTER ("PRCS_Delete", prcsObj) ; DBC_Require (PRCS_IsInitialized == TRUE) ; DBC_Require (prcsObj != NULL) ; DBC_Require (IS_OBJECT_VALID (prcsObj, SIGN_PRCS)) ; if (IS_OBJECT_VALID (prcsObj, SIGN_PRCS)) { prcsObj->signature = SIGN_NULL ; status = FREE_PTR (prcsObj) ; if (DSP_FAILED (status)) { SET_FAILURE_REASON ; } } else { status = DSP_EPOINTER ; SET_FAILURE_REASON ; } TRC_1LEAVE ("PRCS_Delete", status) ; return status ; }
/** ============================================================================ * @func LIST_InsertBefore * * @desc Insert the element before the existing element. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_InsertBefore (IN List * list, IN ListElement * insertElement, IN ListElement * existingElement) { DSP_STATUS status = DSP_SOK ; TRC_3ENTER ("LIST_InsertBefore", list, insertElement, existingElement) ; DBC_Require(list != NULL) ; DBC_Require(insertElement != NULL) ; DBC_Require(existingElement != NULL) ; if ( (list == NULL) || (insertElement == NULL) || (existingElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { existingElement->prev->next = insertElement ; insertElement->prev = existingElement->prev ; insertElement->next = existingElement ; existingElement->prev = insertElement ; } DBC_Assert ( (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list))) || (DSP_FAILED (status))); TRC_1LEAVE ("LIST_InsertBefore", status) ; return status ; }
/** ============================================================================ * @func PRCS_IsSameContext * * @desc Checks if the two clients share same context (address space). * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS PRCS_IsSameContext (IN PrcsObject * client1, IN PrcsObject * client2, OUT Bool * isSame) { DSP_STATUS status = DSP_SOK ; TRC_3ENTER ("PRCS_IsSameContext", client1, client2, isSame) ; DBC_Require (PRCS_IsInitialized == TRUE) ; DBC_Require (IS_OBJECT_VALID (client1, SIGN_PRCS)) ; DBC_Require (IS_OBJECT_VALID (client2, SIGN_PRCS)) ; DBC_Require (isSame != NULL) ; if ( (IS_OBJECT_VALID (client1, SIGN_PRCS) == FALSE) || (IS_OBJECT_VALID (client2, SIGN_PRCS) == FALSE) || (isSame == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (client1->handleToProcess == client2->handleToProcess) { *isSame = TRUE ; } else { *isSame = FALSE ; } } TRC_1LEAVE ("PRCS_IsSameContext", status) ; return status ; }
/** ============================================================================ * @func LIST_RemoveElement * * @desc Removes (unlinks) the given element from the list, if the list is * not empty. Does not free the list element. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_RemoveElement (IN List * list, IN ListElement * element) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_RemoveElement", list, element) ; DBC_Require (list != NULL) ; DBC_Require (element != NULL) ; if ((list == NULL) || (element == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (!LIST_IsEmpty (list)) { element->prev->next = element->next ; element->next->prev = element->prev ; /* set elem fields to NULL to prevent illegal references */ element->next = NULL ; element->prev = NULL ; } else { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } } TRC_1LEAVE ("LIST_RemoveElement", status) ; return status ; }
/* * ======== DMM_Create ======== * Purpose: * Create a dynamic memory manager object. */ DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr, struct DEV_OBJECT *hDevObject, IN CONST struct DMM_MGRATTRS *pMgrAttrs) { struct DMM_OBJECT *pDmmObject = NULL; DSP_STATUS status = DSP_SOK; DBC_Require(cRefs > 0); DBC_Require(phDmmMgr != NULL); GT_3trace(DMM_debugMask, GT_ENTER, "DMM_Create: phDmmMgr: 0x%x hDevObject: " "0x%x pMgrAttrs: 0x%x\n", phDmmMgr, hDevObject, pMgrAttrs); *phDmmMgr = NULL; /* create, zero, and tag a cmm mgr object */ MEM_AllocObject(pDmmObject, struct DMM_OBJECT, DMMSIGNATURE); if (pDmmObject != NULL) { status = SYNC_InitializeCS(&pDmmObject->hDmmLock); if (DSP_SUCCEEDED(status)) *phDmmMgr = pDmmObject; else DMM_Destroy(pDmmObject); } else { GT_0trace(DMM_debugMask, GT_7CLASS, "DMM_Create: Object Allocation " "Failure(DMM Object)\n"); status = DSP_EMEMORY; } GT_2trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_Create status %x pDmmObject %x\n", status, pDmmObject); return status; }
/** ============================================================================ * @func LIST_Next * * @desc Returns a pointer to the next element of the list, or NULL if * the next element is the head of the list or the list is empty. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_Next (IN List * list, IN ListElement * currentElement, OUT ListElement ** nextElement) { DSP_STATUS status = DSP_SOK ; TRC_3ENTER ("LIST_Next", list, currentElement, nextElement) ; DBC_Require (list != NULL) ; DBC_Require (currentElement != NULL) ; DBC_Require (nextElement != NULL) ; if ( (list == NULL) || (currentElement == NULL) || (nextElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { *nextElement = NULL ; /* prime the variable */ if (!LIST_IsEmpty (list)) { if (currentElement->next != &list->head) { *nextElement = currentElement->next ; } } } TRC_1LEAVE ("LIST_Next", status) ; return status ; }
/** ============================================================================ * @func ISR_Enable * * @desc Enables the specified ISR. * This function calls enable_irq () to enable the ISR. * enble_irq() function doesn't return any value so this function * assumes it was successful. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS ISR_Enable (IN IsrObject * isrObj) { DSP_STATUS status = DSP_SOK ; TRC_1ENTER ("ISR_Enable", isrObj) ; DBC_Require (ISR_IsInitialized == TRUE) ; DBC_Require (isrObj != NULL) ; DBC_Require (IS_OBJECT_VALID (isrObj, SIGN_ISR)) ; DBC_Require ( (isrObj != NULL) && (ISR_InstalledIsrs [isrObj->dspId][isrObj->irq] == isrObj)) ; if (IS_OBJECT_VALID (isrObj, SIGN_ISR) == FALSE) { status = DSP_EPOINTER ; SET_FAILURE_REASON ; } else if (ISR_InstalledIsrs [isrObj->dspId][isrObj->irq] != isrObj) { status = DSP_EACCESSDENIED ; SET_FAILURE_REASON ; } else { enable_irq (isrObj->irq) ; isrObj->enabled = TRUE ; } TRC_1LEAVE ("ISR_Enable", status) ; return status ; }
/** ============================================================================ * @func MEM_Calloc * * @desc Allocates the specified number of bytes and memory is set to zero. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS MEM_Calloc (OUT Void ** ptr, IN Uint32 cBytes, IN OUT Pvoid arg) { DSP_STATUS status = DSP_SOK ; Uint32 i ; TRC_3ENTER ("MEM_Calloc", ptr, cBytes, arg) ; DBC_Require (ptr != NULL) ; DBC_Require (MEM_IsInitialized == TRUE) ; DBC_Require (cBytes != 0) ; status = MEM_Alloc (ptr, cBytes, arg) ; if (DSP_SUCCEEDED (status)) { for (i = 0 ; i < cBytes ; i++) { (*(Uint8 **) ptr)[i] = 0 ; } } DBC_Ensure ( ((ptr == NULL) && DSP_FAILED (status)) || ((ptr != NULL) && (*ptr != NULL) && DSP_SUCCEEDED (status)) || ((ptr != NULL) && (*ptr == NULL) && DSP_FAILED (status))) ; TRC_1LEAVE ("MEM_Calloc", status) ; return status ; }
/* * ======== STRM_RegisterNotify ======== * Purpose: * Register to be notified on specific events for this stream. */ DSP_STATUS STRM_RegisterNotify(struct STRM_OBJECT *hStrm, u32 uEventMask, u32 uNotifyType, struct DSP_NOTIFICATION *hNotification) { struct WMD_DRV_INTERFACE *pIntfFxns; DSP_STATUS status = DSP_SOK; DBC_Require(cRefs > 0); DBC_Require(hNotification != NULL); if ((uEventMask & ~((DSP_STREAMIOCOMPLETION) | DSP_STREAMDONE)) != 0) { status = DSP_EVALUE; } else { if (uNotifyType != DSP_SIGNALEVENT) status = DSP_ENOTIMPL; } if (DSP_SUCCEEDED(status)) { pIntfFxns = hStrm->hStrmMgr->pIntfFxns; status = (*pIntfFxns->pfnChnlRegisterNotify)(hStrm->hChnl, uEventMask, uNotifyType, hNotification); } /* ensure we return a documented return code */ DBC_Ensure(DSP_SUCCEEDED(status) || status == DSP_EHANDLE || status == DSP_ETIMEOUT || status == DSP_ETRANSLATE || status == DSP_ENOTIMPL || status == DSP_EFAIL); return status; }
/** ============================================================================ * @func LDRV_init * * @desc Allocates resources and initializes the LDRV component for a DSP. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LDRV_init (IN ProcessorId procId, IN LINKCFG_DspConfig * dspCfg) { DSP_STATUS status = DSP_SOK ; Char8 * dspName = NULL ; TRC_2ENTER ("LDRV_init", procId, dspCfg) ; DBC_Require (LDRV_LinkCfgPtr != NULL) ; DBC_Require (IS_VALID_PROCID (procId)) ; /* ------------------------------------------------------------------------ * Get the pointer to kernel-side APUDRV configuration structure. * ------------------------------------------------------------------------ */ if (dspCfg != NULL) { if (LDRV_LinkCfgPtr->dspConfigs [procId] != NULL) { /* First free the previously read config values */ status = LDRV_freeLinkDspCfg (procId, LDRV_LinkCfgPtr) ; if (DSP_FAILED (status)) { SET_FAILURE_REASON ; } } if (DSP_SUCCEEDED (status)) { status = LDRV_getLinkDspCfg (procId, dspCfg, LDRV_LinkCfgPtr) ; if (DSP_FAILED (status)) { SET_FAILURE_REASON ; LDRV_exit (procId) ; } } } else { if (LDRV_LinkCfgPtr->dspConfigs [procId] == NULL) { PRINT_Printf ("For multi-app support, Please pass valid DSP") ; PRINT_Printf ("Config values through PROC_attach.\n") ; status = DSP_ECONFIG ; SET_FAILURE_REASON ; } } /* ------------------------------------------------------------------------ * Plug the correct configuration mapping information for APU DRIVER. * ------------------------------------------------------------------------ */ if (DSP_SUCCEEDED (status)) { dspName = LDRV_LinkCfgPtr->dspConfigs [procId]->dspObject->name ; status = CFGMAP_attachObject (procId, dspName) ; if (DSP_FAILED (status)) { SET_FAILURE_REASON ; LDRV_exit (procId) ; } } TRC_1LEAVE ("LDRV_init", status) ; return status ; }
/* * ======== WMD_CHNL_Create ======== * Create a channel manager object, responsible for opening new channels * and closing old ones for a given board. */ DSP_STATUS WMD_CHNL_Create(OUT struct CHNL_MGR **phChnlMgr, struct DEV_OBJECT *hDevObject, IN CONST struct CHNL_MGRATTRS *pMgrAttrs) { DSP_STATUS status = DSP_SOK; struct CHNL_MGR *pChnlMgr = NULL; s32 cChannels; /* Check DBC requirements: */ DBC_Require(phChnlMgr != NULL); DBC_Require(pMgrAttrs != NULL); DBC_Require(pMgrAttrs->cChannels > 0); DBC_Require(pMgrAttrs->cChannels <= CHNL_MAXCHANNELS); DBC_Require(pMgrAttrs->uWordSize != 0); /* Allocate channel manager object: */ MEM_AllocObject(pChnlMgr, struct CHNL_MGR, CHNL_MGRSIGNATURE); if (pChnlMgr) { /* The cChannels attr must equal the # of supported * chnls for each transport(# chnls for PCPY = DDMA = * ZCPY): i.e. pMgrAttrs->cChannels = CHNL_MAXCHANNELS = * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS. */ DBC_Assert(pMgrAttrs->cChannels == CHNL_MAXCHANNELS); cChannels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY; /* Create array of channels: */ pChnlMgr->apChannel = MEM_Calloc( sizeof(struct CHNL_OBJECT *) * cChannels, MEM_NONPAGED); if (pChnlMgr->apChannel) { /* Initialize CHNL_MGR object: */ /* Shared memory driver. */ pChnlMgr->dwType = CHNL_TYPESM; pChnlMgr->uWordSize = pMgrAttrs->uWordSize; /* total # chnls supported */ pChnlMgr->cChannels = cChannels; pChnlMgr->cOpenChannels = 0; pChnlMgr->dwOutputMask = 0; pChnlMgr->dwLastOutput = 0; pChnlMgr->hDevObject = hDevObject; if (DSP_SUCCEEDED(status)) status = SYNC_InitializeDPCCS( &pChnlMgr->hCSObj); } else { status = DSP_EMEMORY; } } else { status = DSP_EMEMORY; } if (DSP_FAILED(status)) { WMD_CHNL_Destroy(pChnlMgr); *phChnlMgr = NULL; } else { /* Return channel manager object to caller... */ *phChnlMgr = pChnlMgr; } return status; }
/** ============================================================================ * @func LDRV_MPLIST_removeElement * * @desc Removes (unlinks) the given element from the list, if the list is * not empty. Does not free the list element. This function works on * the list object and element fields in DSP address space.If the * element is from pool memory, it does the invalidate and writeback * operations on the element. If the element is from a non pool shared * memory, invalidate writeback operations are not performed. * * @modif None. * ============================================================================ */ EXPORT_API Void LDRV_MPLIST_removeElement (IN ProcessorId dspId, IN List * list, IN ListElement * element ) { PoolId poolId = POOL_INVALIDID ; LDRV_MPLIST_Object * mplistState ; ListElement * temp ; TRC_4ENTER ("LDRV_MPLIST_removeElement", dspId, list, element, poolId) ; DBC_Require (IS_VALID_PROCID (dspId)) ; DBC_Require (list != NULL) ; DBC_Require (element != NULL) ; DBC_Assert (LDRV_MPLIST_IsInitialized [dspId] == TRUE) ; mplistState = &(LDRV_MPLIST_State [dspId]) ; if (LDRV_MPLIST_isEmpty (dspId, list) == FALSE) { temp = (ListElement *) DSP_addrConvert (dspId, SWAP_LONG ((Uint32) (element->prev), mplistState->wordSwap), DspToGpp) ; LDRV_POOL_getPoolId (dspId, temp, AddrType_Knl, &poolId ); if (IS_VALID_POOLID (poolId)) { LDRV_POOL_invalidate (poolId, temp, sizeof (ListElement)) ; } temp->next = element->next ; if (IS_VALID_POOLID (poolId)) { LDRV_POOL_writeback (poolId, temp, sizeof (ListElement)) ; } temp = (ListElement *) DSP_addrConvert (dspId, SWAP_LONG ((Uint32) (element->next), mplistState->wordSwap), DspToGpp) ; LDRV_POOL_getPoolId (dspId, temp, AddrType_Knl, &poolId ); if (IS_VALID_POOLID (poolId)) { LDRV_POOL_invalidate (poolId, temp, sizeof (ListElement)) ; } temp->prev = element->prev ; if (IS_VALID_POOLID (poolId)) { LDRV_POOL_writeback (poolId, temp, sizeof (ListElement)) ; } } TRC_0LEAVE ("LDRV_MPLIST_removeElement") ; }
/** ============================================================================ * @func KFILEDEF_Read * * @desc Reads a specified number of items of specified size * bytes from file to a buffer. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS KFILEDEF_Read (IN OUT Char8 * buffer, IN Uint32 size, IN Uint32 count, IN Void * fileHandle) { DSP_STATUS status = DSP_SOK ; Int32 bytesRead = 0 ; mm_segment_t fs ; KFILEDEF_Object * fileObj = NULL ; TRC_4ENTER ("KFILEDEF_Read", buffer, size, count, fileHandle) ; DBC_Require (fileHandle != NULL) ; DBC_Require (buffer != NULL) ; if (buffer == NULL) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else if ((size != 0) && (count != 0)) { fileObj = (KFILEDEF_Object *) fileHandle ; if ((fileObj->curPos + (size * count)) > fileObj->size) { status = DSP_ERANGE ; SET_FAILURE_REASON ; } else { /* read from file */ fs = get_fs () ; set_fs (KERNEL_DS) ; bytesRead = fileObj->fileDesc->f_op->read (fileObj->fileDesc, buffer, size * count, &(fileObj->fileDesc->f_pos)); set_fs (fs) ; if (bytesRead >= 0) { fileObj->curPos += bytesRead ; DBC_Assert ((bytesRead / size) == (Uint32) count) ; } else { status = DSP_EFILE; TRC_2PRINT (TRC_LEVEL1, "File Read failed with status [0x%x]\n" "Error value[0x%x]\n", status, bytesRead) ; } } } TRC_1LEAVE ("KFILEDEF_Read", status) ; return status ; }
/* * ======== STRM_Delete ======== * Purpose: * Delete the STRM Manager Object. */ void STRM_Delete(struct STRM_MGR *hStrmMgr) { DBC_Require(cRefs > 0); DBC_Require(MEM_IsValidHandle(hStrmMgr, STRMMGR_SIGNATURE)); DeleteStrmMgr(hStrmMgr); DBC_Ensure(!MEM_IsValidHandle(hStrmMgr, STRMMGR_SIGNATURE)); }
/* * ======== STRM_GetInfo ======== * Purpose: * Retrieves information about a stream. */ DSP_STATUS STRM_GetInfo(struct STRM_OBJECT *hStrm, OUT struct STRM_INFO *pStreamInfo, u32 uStreamInfoSize) { struct WMD_DRV_INTERFACE *pIntfFxns; struct CHNL_INFO chnlInfo; DSP_STATUS status = DSP_SOK; void *pVirtBase = NULL; /* NULL if no SM used */ DBC_Require(cRefs > 0); DBC_Require(pStreamInfo != NULL); DBC_Require(uStreamInfoSize >= sizeof(struct STRM_INFO)); if (uStreamInfoSize < sizeof(struct STRM_INFO)) { /* size of users info */ status = DSP_ESIZE; } if (DSP_FAILED(status)) goto func_end; pIntfFxns = hStrm->hStrmMgr->pIntfFxns; status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo); if (DSP_FAILED(status)) goto func_end; if (hStrm->hXlator) { /* We have a translator */ DBC_Assert(hStrm->uSegment > 0); CMM_XlatorInfo(hStrm->hXlator, (u8 **)&pVirtBase, 0, hStrm->uSegment, false); } pStreamInfo->uSegment = hStrm->uSegment; pStreamInfo->lMode = hStrm->lMode; pStreamInfo->pVirtBase = pVirtBase; pStreamInfo->pUser->uNumberBufsAllowed = hStrm->uNumBufs; pStreamInfo->pUser->uNumberBufsInStream = chnlInfo.cIOCs + chnlInfo.cIOReqs; /* # of bytes transferred since last call to DSPStream_Idle() */ pStreamInfo->pUser->ulNumberBytes = chnlInfo.cPosition; pStreamInfo->pUser->hSyncObjectHandle = chnlInfo.hEvent; /* Determine stream state based on channel state and info */ if (chnlInfo.dwState & CHNL_STATEEOS) { pStreamInfo->pUser->ssStreamState = STREAM_DONE; } else { if (chnlInfo.cIOCs > 0) pStreamInfo->pUser->ssStreamState = STREAM_READY; else if (chnlInfo.cIOReqs > 0) pStreamInfo->pUser->ssStreamState = STREAM_PENDING; else pStreamInfo->pUser->ssStreamState = STREAM_IDLE; } func_end: return status; }
/* * ======== STRM_FreeBuffer ======== * Purpose: * Frees the buffers allocated for a stream. */ DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, u8 **apBuffer, u32 uNumBufs) { DSP_STATUS status = DSP_SOK; u32 i = 0; #ifndef RES_CLEANUP_DISABLE DSP_STATUS res_status = DSP_SOK; u32 hProcess; HANDLE pCtxt = NULL; HANDLE hDrvObject; HANDLE hSTRMRes = NULL; #endif DBC_Require(cRefs > 0); DBC_Require(apBuffer != NULL); GT_3trace(STRM_debugMask, GT_ENTER, "STRM_FreeBuffer: hStrm: 0x%x\t" "apBuffer: 0x%x\tuNumBufs: 0x%x\n", hStrm, apBuffer, uNumBufs); if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) status = DSP_EHANDLE; if (DSP_SUCCEEDED(status)) { for (i = 0; i < uNumBufs; i++) { DBC_Assert(hStrm->hXlator != NULL); status = CMM_XlatorFreeBuf(hStrm->hXlator, apBuffer[i]); if (DSP_FAILED(status)) { GT_0trace(STRM_debugMask, GT_7CLASS, "STRM_FreeBuffer: DSP_FAILED" " to free shared memory.\n"); break; } apBuffer[i] = NULL; } } #ifndef RES_CLEANUP_DISABLE /* Update the node and stream resource status */ /* Return PID instead of process handle */ hProcess = current->pid; res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); if (DSP_SUCCEEDED(res_status)) { DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, &pCtxt, NULL, 0); if (pCtxt != NULL) { if (DRV_GetSTRMResElement(hStrm, hSTRMRes, pCtxt) != DSP_ENOTFOUND) { DRV_ProcUpdateSTRMRes(uNumBufs-i, hSTRMRes, pCtxt); } } } #endif return status; }