/* * ======== 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; }
/* * ======== STRM_Reclaim ======== * Purpose: * Relcaims a buffer from a stream. */ DSP_STATUS STRM_Reclaim(struct STRM_OBJECT *hStrm, OUT u8 **pBufPtr, u32 *pulBytes, u32 *pulBufSize, u32 *pdwArg) { struct WMD_DRV_INTERFACE *pIntfFxns; struct CHNL_IOC chnlIOC; DSP_STATUS status = DSP_SOK; void *pTmpBuf = NULL; DBC_Require(cRefs > 0); DBC_Require(pBufPtr != NULL); DBC_Require(pulBytes != NULL); DBC_Require(pdwArg != NULL); GT_4trace(STRM_debugMask, GT_ENTER, "STRM_Reclaim: hStrm: 0x%x\tpBufPtr: 0x%x" "\tpulBytes: 0x%x\tpdwArg: 0x%x\n", hStrm, pBufPtr, pulBytes, pdwArg); if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { status = DSP_EHANDLE; goto func_end; } pIntfFxns = hStrm->hStrmMgr->pIntfFxns; status = (*pIntfFxns->pfnChnlGetIOC)(hStrm->hChnl, hStrm->uTimeout, &chnlIOC); if (DSP_FAILED(status)) { GT_1trace(STRM_debugMask, GT_6CLASS, "STRM_Reclaim: GetIOC failed! " "Status = 0x%x\n", status); } else { *pulBytes = chnlIOC.cBytes; if (pulBufSize) *pulBufSize = chnlIOC.cBufSize; *pdwArg = chnlIOC.dwArg; if (!CHNL_IsIOComplete(chnlIOC)) { if (CHNL_IsTimedOut(chnlIOC)) { status = DSP_ETIMEOUT; } else { /* Allow reclaims after idle to succeed */ if (!CHNL_IsIOCancelled(chnlIOC)) status = DSP_EFAIL; } } /* Translate zerocopy buffer if channel not canceled. */ if (DSP_SUCCEEDED(status) && (!CHNL_IsIOCancelled(chnlIOC)) && (hStrm->lMode == STRMMODE_ZEROCOPY)) { /* * This is a zero-copy channel so chnlIOC.pBuf * contains the DSP address of SM. We need to * translate it to a virtual address for the user * thread to access. * Note: Could add CMM_DSPPA2VA to CMM in the future. */ pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, chnlIOC.pBuf, CMM_DSPPA2PA); if (pTmpBuf != NULL) { /* now convert this GPP Pa to Va */ pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, pTmpBuf, CMM_PA2VA); } if (pTmpBuf == NULL) { GT_0trace(STRM_debugMask, GT_7CLASS, "STRM_Reclaim: Failed " "SM translation!\n"); status = DSP_ETRANSLATE; } chnlIOC.pBuf = pTmpBuf; } *pBufPtr = chnlIOC.pBuf; } func_end: /* ensure we return a documented return code */ DBC_Ensure(DSP_SUCCEEDED(status) || status == DSP_EHANDLE || status == DSP_ETIMEOUT || status == DSP_ETRANSLATE || status == DSP_EFAIL); return status; }