/* * ======== 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; }
/* * ======== 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; }
/* * ======== STRM_AllocateBuffer ======== * Purpose: * Allocates buffers for a stream. */ DSP_STATUS STRM_AllocateBuffer(struct STRM_OBJECT *hStrm, u32 uSize, OUT u8 **apBuffer, u32 uNumBufs, struct PROCESS_CONTEXT *pr_ctxt) { DSP_STATUS status = DSP_SOK; u32 uAllocated = 0; u32 i; HANDLE hSTRMRes; DBC_Require(cRefs > 0); DBC_Require(apBuffer != NULL); /* * Allocate from segment specified at time of stream open. */ if (uSize == 0) status = DSP_ESIZE; if (DSP_FAILED(status)) goto func_end; for (i = 0; i < uNumBufs; i++) { DBC_Assert(hStrm->hXlator != NULL); (void)CMM_XlatorAllocBuf(hStrm->hXlator, &apBuffer[i], uSize); if (apBuffer[i] == NULL) { status = DSP_EMEMORY; uAllocated = i; break; } } if (DSP_FAILED(status)) STRM_FreeBuffer(hStrm, apBuffer, uAllocated, pr_ctxt); if (DSP_FAILED(status)) goto func_end; if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pr_ctxt) != DSP_ENOTFOUND) DRV_ProcUpdateSTRMRes(uNumBufs, hSTRMRes); func_end: return status; }
/* * ======== STRM_Close ======== * Purpose: * Close a stream opened with STRM_Open(). */ DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm, struct PROCESS_CONTEXT *pr_ctxt) { struct WMD_DRV_INTERFACE *pIntfFxns; struct CHNL_INFO chnlInfo; DSP_STATUS status = DSP_SOK; HANDLE hSTRMRes; DBC_Require(cRefs > 0); GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Close: hStrm: 0x%x\n", hStrm); /* Have all buffers been reclaimed? If not, return * DSP_EPENDING */ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo); DBC_Assert(DSP_SUCCEEDED(status)); if (chnlInfo.cIOCs > 0 || chnlInfo.cIOReqs > 0) status = DSP_EPENDING; else status = DeleteStrm(hStrm); if (DSP_FAILED(status)) goto func_end; if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pr_ctxt) != DSP_ENOTFOUND) DRV_ProcRemoveSTRMResElement(hSTRMRes, pr_ctxt); func_end: DBC_Ensure(status == DSP_SOK || status == DSP_EHANDLE || status == DSP_EPENDING || status == DSP_EFAIL); return status; }
/* * ======== STRM_Close ======== * Purpose: * Close a stream opened with STRM_Open(). */ DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm) { struct WMD_DRV_INTERFACE *pIntfFxns; struct CHNL_INFO chnlInfo; DSP_STATUS status = DSP_SOK; #ifndef RES_CLEANUP_DISABLE u32 hProcess; HANDLE pCtxt = NULL; HANDLE hDrvObject; HANDLE hSTRMRes; DSP_STATUS res_status = DSP_SOK; #endif DBC_Require(cRefs > 0); GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Close: hStrm: 0x%x\n", hStrm); if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { status = DSP_EHANDLE; } else { /* Have all buffers been reclaimed? If not, return * DSP_EPENDING */ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo); DBC_Assert(DSP_SUCCEEDED(status)); if (chnlInfo.cIOCs > 0 || chnlInfo.cIOReqs > 0) { status = DSP_EPENDING; } else { status = DeleteStrm(hStrm); if (DSP_FAILED(status)) { /* we already validated the handle. */ DBC_Assert(status != DSP_EHANDLE); /* make sure we return a documented result */ status = DSP_EFAIL; } } } #ifndef RES_CLEANUP_DISABLE if (DSP_FAILED(status)) goto func_end; /* 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_FAILED(res_status)) goto func_end; DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, &pCtxt, NULL, 0); if (pCtxt != NULL) { if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pCtxt) != DSP_ENOTFOUND) { DRV_ProcRemoveSTRMResElement(hSTRMRes, pCtxt); } } func_end: #endif DBC_Ensure(status == DSP_SOK || status == DSP_EHANDLE || status == DSP_EPENDING || status == DSP_EFAIL); return status; }
/* * ======== STRM_AllocateBuffer ======== * Purpose: * Allocates buffers for a stream. */ DSP_STATUS STRM_AllocateBuffer(struct STRM_OBJECT *hStrm, u32 uSize, OUT u8 **apBuffer, u32 uNumBufs) { DSP_STATUS status = DSP_SOK; u32 uAllocated = 0; u32 i; #ifndef RES_CLEANUP_DISABLE DSP_STATUS res_status = DSP_SOK; u32 hProcess; HANDLE pCtxt = NULL; HANDLE hDrvObject; HANDLE hSTRMRes; #endif DBC_Require(cRefs > 0); DBC_Require(apBuffer != NULL); GT_4trace(STRM_debugMask, GT_ENTER, "STRM_AllocateBuffer: hStrm: 0x%x\t" "uSize: 0x%x\tapBuffer: 0x%x\tuNumBufs: 0x%x\n", hStrm, uSize, apBuffer, uNumBufs); if (MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { /* * Allocate from segment specified at time of stream open. */ if (uSize == 0) status = DSP_ESIZE; } if (DSP_FAILED(status)) { status = DSP_EHANDLE; goto func_end; } for (i = 0; i < uNumBufs; i++) { DBC_Assert(hStrm->hXlator != NULL); (void)CMM_XlatorAllocBuf(hStrm->hXlator, &apBuffer[i], uSize); if (apBuffer[i] == NULL) { GT_0trace(STRM_debugMask, GT_7CLASS, "STRM_AllocateBuffer: " "DSP_FAILED to alloc shared memory.\n"); status = DSP_EMEMORY; uAllocated = i; break; } } if (DSP_FAILED(status)) STRM_FreeBuffer(hStrm, apBuffer, uAllocated); #ifndef RES_CLEANUP_DISABLE if (DSP_FAILED(status)) goto func_end; /* Return PID instead of process handle */ hProcess = current->pid; res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); if (DSP_FAILED(res_status)) goto func_end; DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, &pCtxt, NULL, 0); if (pCtxt != NULL) { if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pCtxt) != DSP_ENOTFOUND) { DRV_ProcUpdateSTRMRes(uNumBufs, hSTRMRes, pCtxt); } } #endif func_end: return status; }